com.seanox.pdf.Template Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of seanox-pdf-service Show documentation
Show all versions of seanox-pdf-service Show documentation
PDF service for generating/rendering PDFs based on Open HTML to PDF
/**
* LIZENZBEDINGUNGEN - Seanox Software Solutions ist ein Open-Source-Projekt, im
* Folgenden Seanox Software Solutions oder kurz Seanox genannt.
* Diese Software unterliegt der Version 2 der Apache License.
*
* PDF Service
* Copyright (C) 2020 Seanox Software Solutions
*
* 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 com.seanox.pdf;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
/**
* Abstract class for implementing of template implementations.
*
* About the templates
* As engine {@link Generator} is used, here you can find more details.
* The most important in short form:
*
* #[palceholder]
* Simple placeholder, global or in a section.
*
* #[palceholder-exists]
* Pendant to any placeholder, if it exists.
*
* #[section[[...]]]
* Section/Bock can contain more substructures.
* Sections/blocks are only rendered if a corresponding map entry exists.
*
* ![static-text]
* Placeholder for static text from the ResourceBundle.
* As language {@link Service.Meta#locale} is used.
*
* #[locale]
* Placeholder provided by {@link Service} with the current language.
* Available in all sections (header, content/data, footer).
*
* #[page]
* Placeholder provided by {@link Service} with the current page number.
* Available in sections: header, footer
*
* #[pages]
* Placeholder provided by {@link Service} with the total page number.
* Available in sections: header, footer
*
* Template 3.1x.0x 20200313
* Copyright (C) 2020 Seanox Software Solutions
* Alle Rechte vorbehalten.
*
* @author Seanox Software Solutions
* @version 3.1x.0x 20200313
*/
public abstract class Template extends Service.Template {
/** Naturally sort comparator */
private static class NaturalComparator implements Comparator {
/**
* Normalizes the numeric fragments that they can be sorted.
* @param string string to be escaped
* @return the normalized string
*/
private static String normalize(String string) {
String buffer = "";
string = StringUtils.trimToEmpty(string);
for (String fragment : string.split("(?:(?<=\\d)(?!\\d))|(?:(? map, String key, String value)
throws PreviewDataParserException {
final String PATTERN_EXPRESSION = "^(?i)([a-z](?:[\\w\\-]*\\w)*)((?:\\[\\s*\\d+\\s*\\])*)(\\.([a-z](?:[\\w\\-]*\\w)*)((?:\\[\\s*\\d+\\s*\\])*))*$";
if (!key.matches(PATTERN_EXPRESSION))
throw new PreviewDataParserException("Invalid key: " + key);
if (key.contains(".")) {
String path = key.replaceAll("\\.[^\\.]+$", "");
for (String entry : path.split("\\.")) {
final String PATTERN_LIST_EXPRESSION = "^(.*)\\s*\\[\\s*(\\d+)\\s*\\]$";
if (entry.matches(PATTERN_LIST_EXPRESSION)) {
int index = Integer.valueOf(entry.replaceAll(PATTERN_LIST_EXPRESSION, "$2")).intValue();
entry = entry.replaceAll(PATTERN_LIST_EXPRESSION, "$1").trim();
if (!map.containsKey(entry)
|| !(map.get(entry) instanceof List))
map.put(entry, new ArrayList<>());
List list = (List)map.get(entry);
if (list.size() < index)
throw new PreviewDataParserException("Invalid key index: " + key);
if (list.size() > index) {
if (!(list.get(index) instanceof Map))
list.set(index, new HashMap<>());
} else list.add(index, new HashMap<>());
map = (Map)list.get(index);
} else {
if (!map.containsKey(entry)
|| !(map.get(entry) instanceof Map))
map.put(entry, new HashMap<>());
map = (Map)map.get(entry);
}
}
key = key.replaceAll("^.*\\.", "");
}
map.put(key, value);
}
/**
* Returns the preview data for the template as properties.
* The properties file are in the same package and use the same name.
* e.g. ArticleTemplateImpl -> ArticleTemplateImpl.properties
* @return the preview for one data record as preview
* @throws Exception
* In case of unexpected errors.
*/
protected Properties getPreviewProperties()
throws Exception {
String resource = this.getSourcePath();
resource = resource.replaceAll("[^\\\\/\\.]+$", "") + "properties";
Properties properties = new Properties();
properties.load(this.getResourceStream(resource));
return properties;
}
/**
* Creates preview data based on a properties file corresponding to impl.
* The properties file are in the same package and use the same name.
* e.g. ArticleTemplateImpl -> ArticleTemplateImpl.properties
* @return the data for one data record as preview
* @throws Exception
* In case of unexpected errors.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
protected Map getPreviewData()
throws Exception {
Properties properties = this.getPreviewProperties();
Map map = new HashMap<>();
Set keySet = new TreeSet<>(new NaturalComparator());
keySet.addAll(properties.keySet());
for (Object key : keySet) {
String source = ((String)key);
String target = source.replaceAll("(^\\.+)|(\\.+$)", "");
Template.collectPreviewData(map, target, properties.getProperty(source));
}
return map;
}
/**
* Escapes all characters greater than ASCII 0x7F as HTML code.
* The value {@code null} is used as a space.
* @param text text to escape
* @return the possibly escaped text
*/
static String escapeHtml(String text) {
if (text == null)
return "";
StringBuilder build = new StringBuilder();
for (char digit : text.toCharArray()) {
if (digit > 0x7F)
build.append("").append((int)digit).append(";");
else if (digit == '&')
build.append("&");
else build.append(digit);
}
text = build.toString();
text = text.replaceAll("(\r\n)|(\n\r)|[\r\n]", "
");
return text;
}
/**
* Escapes the text values of/in a Object.
* @param object object to escape
* @return the escaped object
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private static Object escapeHtml(Object object) {
if (object == null)
return "";
if (object instanceof Collection)
return Template.escapeHtml((Collection)object);
if (object instanceof Map)
return Template.escapeHtml((Map)object);
return Template.escapeHtml(String.valueOf(object));
}
/**
* Escapes the text values in a Collection.
* @param collection collection with text values to escape
* @return the Collection with escaped text values
*/
private static Collection
© 2015 - 2024 Weber Informatics LLC | Privacy Policy