com.github.cukedoctor.sectionlayout.DocumentSection Maven / Gradle / Ivy
package com.github.cukedoctor.sectionlayout;
import com.github.cukedoctor.api.CukedoctorDocumentBuilder;
import com.github.cukedoctor.api.DocumentAttributes;
import com.github.cukedoctor.api.model.Feature;
import com.github.cukedoctor.i18n.I18nLoader;
import java.util.*;
import java.util.stream.Stream;
import static com.github.cukedoctor.sectionlayout.Constants.*;
public class DocumentSection implements Section {
private final BuiltInFeaturesSection featuresSection = new BuiltInFeaturesSection() {
@Override
public int getOrder() {
return 2;
}
};
private final Map> featuresBySectionId = new HashMap<>();
private final Section glossary = new BasicSection("Glossary", "glossary", null);
private final Section bibliography = new BasicSection("Bibliography", "bibliography", null);
private final Section index = new BasicSection("Index", "index", null);
private final Set appendixIds = new HashSet<>();
public DocumentSection() {
}
public DocumentSection(Iterable features) {
for (Feature feature : features) {
addFeature(feature);
}
}
@Override
public Section addFeature(Feature feature) {
if (feature.hasIgnoreDocsTag()) return this;
if (isGlossary(feature)) {
glossary.addFeature(feature);
return this;
}
if (isBibliography(feature)) {
bibliography.addFeature(feature);
return this;
}
if (isIndex(feature)) {
index.addFeature(feature);
return this;
}
Optional sectionId = feature.extractTag(SectionTagPattern);
if (!sectionId.isPresent()) {
featuresSection.addFeature(feature);
return this;
}
addFeatureForSection(feature, sectionId.get());
if (feature.hasTag(AppendixTagPattern)) {
appendixIds.add(sectionId.get());
}
return this;
}
private boolean isGlossary(Feature feature) {
return feature.hasTag(GlossaryTagPattern);
}
private boolean isBibliography(Feature feature) {
return feature.hasTag(BibliographyTagPattern);
}
private boolean isIndex(Feature feature) {
return feature.hasTag(IndexTagPattern);
}
private void addFeatureForSection(Feature feature, String sectionId) {
if (featuresBySectionId.containsKey(sectionId)) {
featuresBySectionId.get(sectionId).add(feature);
return;
}
List features = new LinkedList<>();
features.add(feature);
featuresBySectionId.put(sectionId, features);
}
@Override
public String render(CukedoctorDocumentBuilder docBuilder, I18nLoader i18n, DocumentAttributes documentAttributes) {
buildDocument().forEach(section -> docBuilder.append(section.render(docBuilder.createPeerBuilder(), i18n, documentAttributes)));
return docBuilder.toString();
}
private Stream buildDocument() {
List foreSections = new LinkedList<>();
List appendices = new LinkedList<>();
featuresBySectionId.forEach((String sectionId, Collection features) -> {
if (appendixIds.contains(sectionId)) {
appendices.add(new BasicSection(sectionId, "appendix", SubsectionTagPattern).addFeatures(features));
return;
}
foreSections.add(new BasicSection(sectionId, null, SubsectionTagPattern).addFeatures(features));
});
return Stream.concat(
foreSections.stream().sorted(),
Stream.concat(
Stream.of(featuresSection),
Stream.concat(
appendices.stream().sorted(),
Stream.concat(
Stream.of(glossary),
Stream.concat(
Stream.of(bibliography),
Stream.of(index))))));
}
@Override
public int getOrder() {
return Integer.MAX_VALUE;
}
@Override
public Stream getFeatures() {
return buildDocument().flatMap(Section::getFeatures);
}
}