co.l1x.decode.main.template.TemplateProvider Maven / Gradle / Ivy
The newest version!
package co.l1x.decode.main.template;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import co.l1x.decode.lexer.TokenizeContext;
import co.l1x.decode.template.Template;
import co.l1x.decode.template.TemplateLexer;
import co.l1x.decode.util.StringUtil;
/**
* Class for providing a cached access to {@link Template} objects.
*
* Each instance is initialized with plain {@code String} templates, and each is
* only tokenized into a {@link Template} object on demand
*
* @author Dor Levi
*
*/
public class TemplateProvider {
private static final Logger logger = LoggerFactory.getLogger(TemplateProvider.class);
private final TokenizeContext context;
private final Map rawTemplates;
private final Map templates;
/**
* @param context {@link TokenizeContext} for this {@link TemplateProvider}
* @param rawTemplates a {@code Map} from hashes to a simple
* {@code String} representation of templates.
*/
public TemplateProvider(TokenizeContext context, Map rawTemplates) {
this.context = context;
this.rawTemplates = rawTemplates;
this.templates = new ConcurrentHashMap<>();
}
/**
* Returns the {@link Template} matching to the input {@code hash}
*
* If the result {@link Template} was already initialized in the past, returns
* it from cache. Otherwise, will first tokenize the raw {@code String} matching
* this template into a {@link Template} object, cache that, and return it.
*
* @param hash The hash representing the requested {@link Template}
* @return the matching {@link Template}
*/
public Template getTemplate(String hash) {
Template result = this.templates.get(hash);
if (result != null) {
return result;
}
return addTemplate(hash);
}
private Template addTemplate(String hash) {
Template result;
synchronized (this.templates) {
result = templates.get(hash);
if (result == null) {
result = createTemplate(hash);
if (result != null) {
this.templates.put(hash, result);
}
}
}
return result;
}
private Template createTemplate(String hash) {
String rawTemplate = rawTemplates.get(hash);
if (StringUtil.isNullOrEmpty(rawTemplate)) {
logger.warn("No raw template found for {}.", hash);
return null;
}
try {
TemplateLexer lexer = new TemplateLexer(context, hash);
return lexer.tokenize(rawTemplate);
} catch (Exception e) {
logger.error("Failed to build template {} - {}", hash, rawTemplate, e);
return null;
}
}
/**
* {@code warnDuplicates} defaults to {@code true}
*
* @see #fromFile(TokenizeContext, String, boolean)
*
* @param context {@link TokenizeContext} for the created templates.
* @param filename name of the file to read templates from.
* @return resulting {@link TemplateProvider}
*/
public static TemplateProvider fromFile(TokenizeContext context, String filename) {
return fromFile(context, filename, true);
}
/**
* Creates a new {@link TemplateProvider} from the provided {@code context} and
* {@code filename}
*
* If {@code warnDuplicates} is {@code true}, will emit a log warning whenever
* encountering a duplicate template hash in the file.
*
* @param context {@link TokenizeContext} for the created templates.
* @param filename name of the file to read templates from.
* @param warnDuplicates if set to {@code true}, will emit a log warning
* whenever encountering a duplicate template hash in the
* file.
* @return resulting {@link TemplateProvider}
*/
public static TemplateProvider fromFile(TokenizeContext context, String filename, boolean warnDuplicates) {
return new TemplateProvider(context, getEntriesMap(filename, warnDuplicates));
}
private static Map getEntriesMap(String filename, boolean warnDuplicates) {
Map result = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
for (String line; (line = br.readLine()) != null;) {
TemplateEntry entry;
try {
entry = TemplateEntry.fromJson(line);
} catch (Exception e) {
logger.warn("Non matching template entry line - {}.", line, e);
continue;
}
if ((warnDuplicates) && (result.containsKey(entry.templateHash))) {
logger.warn("Encountered duplicate template hash {} in file {}.", entry.templateHash, filename);
continue;
}
result.put(entry.templateHash, entry.template);
}
} catch (Exception e) {
logger.warn("Error while reading template entries from file {}.", filename, e);
}
return result;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy