package folioxml.export.structure;
import folioxml.core.InvalidMarkupException;
import folioxml.export.FileNode;
import folioxml.export.StaticFileNode;
import folioxml.xml.XmlRecord;
import java.util.Deque;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class SlugProvider extends BaseFileSplitter {
public SlugProvider(String levelRegex, String splitOnFieldName) {
super(levelRegex, splitOnFieldName);
}
public SlugProvider(String levelRegex) {
super(levelRegex);
}
public SlugProvider() {
}
private StaticFileNode silentRoot = new StaticFileNode(null);
public void PopulateNodeInfo(XmlRecord r, FileNode f) throws InvalidMarkupException {
//Infobase ID comes in handy when generating the slug
XmlRecord root = r.getRoot();
if (root != null && root.get("infobaseId") != null) {
f.getBag().put("infobase-id", root.get("infobaseId"));
}
f.getBag().put("slug", getSlug(r, f));
f.getBag().put("folio-id", r.get("folioId"));
f.getBag().put("folio-level", r.getLevelType());
f.getAttributes().put("heading", r.get("heading"));
}
public String getSlug(XmlRecord r, FileNode f) throws InvalidMarkupException {
String heading = getHeading(r, f);
String slug = slugify(heading, 100);
if (r.isRootRecord() && (slug == null || slug.isEmpty())) {
Object name = f.getBag().get("infobase-id");
if (name == null) name = "index";
slug = (String) name;
}
FileNode parentScope = f.getParent() == null ? silentRoot : f.getParent();
Integer suffix = incrementSlug(slug, parentScope);
if (suffix > 1) return slug + "-" + suffix;
else return slug;
}
protected String getHeading(XmlRecord r, FileNode f) throws InvalidMarkupException {
String heading = r.get("heading");
if (heading == null) heading = "UNTITLED";
return heading;
}
protected String slugify(String text, int maxLength) {
String slug = text.toLowerCase(Locale.ENGLISH).replaceAll("[^a-zA-Z0-9-_~$]", " ").trim();
slug = slug.replaceAll("[ \t\r\n]+", "-").toLowerCase(Locale.ENGLISH);
if (slug.length() > maxLength) slug = slug.substring(0, maxLength);
return slug;
}
protected Integer incrementSlug(String slug, FileNode scope) {
//Access sibling slugs to ensure uniqueness.
Object oslugs = scope.getBag().get("childSlugs");
if (oslugs == null) {
oslugs = new HashMap<String, Integer>();
scope.getBag().put("childSlugs", oslugs);
}
Map<String, Integer> siblingSlugs = (Map<String, Integer>) oslugs;
if (siblingSlugs.get(slug) == null) {
siblingSlugs.put(slug, 0);
}
//Increment
siblingSlugs.put(slug, siblingSlugs.get(slug) + 1);
return siblingSlugs.get(slug);
}
@Override
public String getRelativePathFor(FileNode fn) {
StringBuilder sb = new StringBuilder();
Deque<StaticFileNode> list = ((StaticFileNode) fn).getAncestors(true);
StaticFileNode n = null;
while (!list.isEmpty()) {
sb.append((String) list.removeLast().getBag().get("slug"));
if (!list.isEmpty()) sb.append('/');
}
return sb.toString();
}
}