package sagan.guides.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import sagan.guides.*;
import sagan.support.ResourceNotFoundException;
import sagan.support.github.RepoContent;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
/**
* Repository implementation providing data access services for understanding docs.
*/
@Component
public class UnderstandingDocs implements DocRepository<UnderstandingDoc, UnderstandingMetadata>, ContentProvider<UnderstandingDoc> {
private static final Log log = LogFactory.getLog(UnderstandingDocs.class);
public static final String CACHE_NAME = "cache.understanding";
public static final Class CACHE_TYPE = UnderstandingDoc.class;
public static final String CACHE_TTL = "${cache.docs.timetolive:0}"; // never expires
private static final String CONTENT_PATH = "/repos/%s/%s/contents/%s/README.md";
private static final String SIDEBAR_PATH = "/repos/%s/%s/contents/%s/SIDEBAR.md";
private final GuideOrganization org;
private final String repoName;
@Autowired
public UnderstandingDocs(GuideOrganization org, @Value("${github.repo.understanding:understanding}") String repoName) {
this.org = org;
this.repoName = repoName;
}
/**
* Find and eagerly populate the {@link UnderstandingDoc} for the given subject.
*
* @throws ResourceNotFoundException if no content exists for the subject.
*/
@Cacheable(value = CACHE_NAME)
public UnderstandingDoc find(String subject) {
UnderstandingDoc doc = new UnderstandingDoc(subject);
populate(doc);
return doc;
}
@Override
public List<UnderstandingMetadata> findAllMetadata() {
return org.getRepoContents("understanding").stream()
.filter(RepoContent::isDirectory)
.map(repoContent -> new UnderstandingDoc(repoContent.getName()))
.collect(Collectors.toList());
}
@Override
public List<UnderstandingDoc> findAll() {
return findAllMetadata()
.stream()
.map(m -> new UnderstandingDoc(m.getSubject()))
.map(t -> populate(t))
.collect(Collectors.toList());
}
@Override
public UnderstandingDoc populate(UnderstandingDoc document) {
String lcSubject = document.getSubject().toLowerCase();
try {
document.setContent(org.getMarkdownFileAsHtml(String.format(CONTENT_PATH, org.getName(), repoName,
lcSubject)));
document.setSidebar(org.getMarkdownFileAsHtml(String.format(SIDEBAR_PATH, org.getName(), repoName,
lcSubject)));
} catch (RestClientException ex) {
String msg = String.format("No understanding doc found for subject '%s'", lcSubject);
throw new ResourceNotFoundException(msg, ex);
}
return document;
}
@CacheEvict(value = CACHE_NAME, allEntries = true)
public void clearCache() {
log.info("Clearing all entries from Understanding docs cache");
}
}