/**
* Copyright [2015] [Christian Loehnert]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.ks.blogging.grav.posts;
import de.ks.blogging.grav.PostDateFormat;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class Header extends HeaderContainer {
private static final Logger log = LoggerFactory.getLogger(Header.class);
private static final String TITLE_KEY = "title";
private static final String DATE_KEY = "date";
private static final String AUTHOR_KEY = "author";
private static final String TAXONOMY_KEY = "taxonomy";
private static final String TAG_KEY = "tag";
private static final String PUBLISHED_KEY = "published";
private static final String CATEGORY_KEY = "category";
protected final DateTimeFormatter american = DateTimeFormatter.ofPattern("MM/dd/yyyy");
protected final DateTimeFormatter europeanDash = DateTimeFormatter.ofPattern("dd-MM-yyyy");
protected final DateTimeFormatter europeanDot = DateTimeFormatter.ofPattern("dd.MM.yyyy");
protected final DateTimeFormatter timeFormatterFull = DateTimeFormatter.ofPattern("HH:mm:ss");
protected final DateTimeFormatter timeFormatterShort = DateTimeFormatter.ofPattern("HH:mm");
protected int bodyStart;
protected final PostDateFormat dateFormat;
public Header(PostDateFormat dateFormat) {
super(null, 0);
this.dateFormat = dateFormat;
}
public String getTitle() {
return getHeaderElement(TITLE_KEY);
}
public Header setTitle(String title) {
return (Header) setHeaderElement(TITLE_KEY, title);
}
public String getAuthor() {
return getHeaderElement(AUTHOR_KEY);
}
public Header setAuthor(String author) {
return (Header) setHeaderElement(AUTHOR_KEY, author);
}
public String getCategory() {
return getOrCreateChildContainer(TAXONOMY_KEY).getHeaderElement(CATEGORY_KEY);
}
public Header setCategory(String category) {
HeaderContainer childContainer = getOrCreateChildContainer(TAXONOMY_KEY);
childContainer.setHeaderElement(CATEGORY_KEY, category);
return this;
}
public boolean isPublished() {
return Boolean.valueOf(elements.getOrDefault(PUBLISHED_KEY, "true"));
}
public Header setPublished(boolean published) {
return (Header) setHeaderElement(PUBLISHED_KEY, String.valueOf(published));
}
public String getDate() {
return getHeaderElement(DATE_KEY);
}
public Header setDate(String date) {
return (Header) setHeaderElement(DATE_KEY, date);
}
public Optional<LocalDate> getLocalDate() {
try {
String dateString = getDate();
if (dateString != null) {
String[] split = dateString.split(" ");
for (String string : split) {
boolean isTime = string.contains(":");
boolean isDate = !isTime;
boolean americanDate = isDate && string.contains("/");
boolean europeanDashDate = isDate && string.contains("-");
boolean europeanDotDate = isDate && string.contains(".");
if (americanDate) {
return Optional.of(LocalDate.parse(string, american));
}
if (europeanDashDate) {
return Optional.of(LocalDate.parse(string, europeanDash));
}
if (europeanDotDate) {
return Optional.of(LocalDate.parse(string, europeanDot));
}
}
}
} catch (DateTimeParseException e) {
//
}
return Optional.empty();
}
public Optional<LocalDateTime> getLocalDateTime() {
Optional<LocalDate> date = getLocalDate();
LocalTime time = null;
String dateString = getDate();
if (dateString != null) {
String[] split = dateString.split(" ");
for (String string : split) {
boolean isTime = string.contains(":");
if (isTime) {
try {
time = LocalTime.parse(string.trim(), timeFormatterFull);
} catch (DateTimeParseException e) {
time = LocalTime.parse(string.trim(), timeFormatterShort);
}
}
}
}
if (time == null || !date.isPresent()) {
return Optional.empty();
} else {
return Optional.of(LocalDateTime.of(date.get(), time));
}
}
public Header setLocalDate(LocalDate date) {
String dateString;
PostDateFormat defaultDateFormat = getDateFormat();
if (defaultDateFormat == PostDateFormat.AMERICAN) {
dateString = american.format(date);
} else {
dateString = europeanDot.format(date);
}
return (Header) setHeaderElement(DATE_KEY, dateString);
}
public Header setLocalDateTime(LocalDateTime dateTime) {
String dateString;
PostDateFormat defaultDateFormat = getDateFormat();
if (defaultDateFormat == PostDateFormat.AMERICAN) {
dateString = american.format(dateTime);
} else {
dateString = europeanDot.format(dateTime);
}
String timeString = timeFormatterFull.format(dateTime);
return (Header) setHeaderElement(DATE_KEY, dateString + " " + timeString);
}
protected PostDateFormat getDateFormat() {
return dateFormat;
}
public String getTagString() {
String tagsString = getOrCreateChildContainer(TAXONOMY_KEY).getHeaderElement(TAG_KEY);
if (tagsString != null && !tagsString.isEmpty()) {
tagsString = StringUtils.remove(tagsString, "[");
tagsString = StringUtils.remove(tagsString, "]");
return tagsString;
}
return "";
}
public Header setTagString(String tagsString) {
HeaderContainer childContainer = getOrCreateChildContainer(TAXONOMY_KEY);
StringBuilder builder = new StringBuilder();
builder.append("[");
builder.append(tagsString);
builder.append("]");
childContainer.setHeaderElement(TAG_KEY, builder.toString());
return this;
}
public List<String> getTags() {
LinkedList<String> retval = new LinkedList<>();
String tagsString = getOrCreateChildContainer(TAXONOMY_KEY).getHeaderElement(TAG_KEY);
if (tagsString != null && !tagsString.isEmpty()) {
tagsString = StringUtils.remove(tagsString, "[");
tagsString = StringUtils.remove(tagsString, "]");
String[] split = StringUtils.split(tagsString, ',');
for (String tag : split) {
retval.add(tag.trim());
}
}
return retval;
}
public Header setTags(String... tags) {
return setTags(Arrays.asList(tags));
}
public Header setTags(List<String> tags) {
if (tags.isEmpty()) {
return this;
} else {
HeaderContainer childContainer = getOrCreateChildContainer(TAXONOMY_KEY);
StringBuilder builder = new StringBuilder();
builder.append("[");
String tagsString = tags.stream().collect(Collectors.joining(", "));
builder.append(tagsString);
builder.append("]");
childContainer.setHeaderElement(TAG_KEY, builder.toString());
return this;
}
}
public String writeHeader() {
StringBuilder builder = new StringBuilder();
builder.append("---\n");
writeContent(builder);
builder.append("---\n");
return builder.toString();
}
public Header read(List<String> lines) {
int start = -1;
int index = 0;
LinkedList<String> headerLines = new LinkedList<>();
for (String line : lines) {
if (line.trim().equals("---")) {
if (start == -1) {
start = index;
log.debug("Found start of header in line {}", start);
} else {
log.debug("Found end of header in line {}", index);
this.bodyStart = index + 1;
break;
}
}
if (start >= 0) {
headerLines.add(line);
}
index++;
}
readHeaderLines(headerLines.listIterator());
return this;
}
public int getBodyStart() {
return bodyStart;
}
}