All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.java.de.k3b.util.StringTemplateEngine Maven / Gradle / Ivy

/*
 * Copyright (c) 2015-2016 by k3b.
 *
 * This file is part of k3b-geoHelper library.
 *
 * 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.k3b.util;

import java.util.ListIterator;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Engine that replaces all occurences of ${name} with corresponding values from callback defined in {@link IValueResolver}.
* * * new StringTemplate(valueResolver).format("hello ${first.name}!") * * * will produce "hello world!" if valueResolver.get("first","name") returns "world" * * Created by k3b on 01.04.2015. */ public class StringTemplateEngine { /** * callback for {@link StringTemplateEngine} to resolve the values for names. * * * new StringTemplate(valueResolver).format("hello ${first.name}!") * * * will produce "hello world!" if valueResolver.get("first","name") returns "world" * * Created by k3b on 01.04.2015. */ public interface IValueResolver { String get(String className, String propertyName, String templateParameter); } /** used to convert ${name} to corresponding value */ protected IValueResolver valueResolver = null; /** if {@link StringTemplateEngine#sedDebugEnabled(boolean)} is set to true. * this stack will contain debugbessages as callstack */ protected Stack debugStack = null; // new Stack(); /** contain last processing error or null if there is no (new) error */ private StringBuilder errors = null; // matches ${a.b} private static final Pattern pattern = Pattern.compile("\\$\\{([^ \\.\\}]+)\\.([^ }]+)\\}"); /** creates the engine with {@link IValueResolver}. */ public StringTemplateEngine(IValueResolver valueResolver) { this.valueResolver = valueResolver; } /** return strue, if value contains tempate parameters */ protected boolean hasParameters(String value) { return ((value != null) && (value.contains("${"))); } /** translates tmeplate to string. */ public String format(String template) { if (template == null) { return null; } final StringBuffer buffer = new StringBuffer(); final Matcher match = pattern.matcher(template); while (match.find()) { final String templateParameter = match.group(0); final String className = match.group(1); final String propertyName = match.group(2); debugPush(templateParameter); String resolverResult = valueResolver.get(className, propertyName, templateParameter); resolverResult = onResolverResult(templateParameter, resolverResult); if (resolverResult != null) { match.appendReplacement(buffer, resolverResult); } else { match.appendReplacement(buffer, ""); } debugPop(); } match.appendTail(buffer); return buffer.toString(); } /** called for every parameter match. Is used to collect debug infos. */ protected String onResolverResult(String templateParameter, String resolverResult) { // log error if resolve failed if ((errors != null) && (resolverResult == null)) { this.errors .append(templateParameter) .append(" not found in ") .append(getDebugStackTrace()) .append("\n"); } return resolverResult; } /** en- or disables debugging mode. */ public StringTemplateEngine sedDebugEnabled(boolean enabled) { if (enabled) { this.debugStack = new Stack(); errors = new StringBuilder(); } else { this.debugStack = null; errors = null; } return this; } /** debug implementation: push to stack. */ protected void debugPush(String parameter) { if (debugStack != null) { if (debugStack.contains(parameter)) { final String errorMessage = this.getClass().toString() + ".format() : " + parameter + " - endless recursion detected " + getDebugStackTrace(); if (errors != null) { this.errors .append(errorMessage) .append("\n"); } throw new StackOverflowError(errorMessage); } debugStack.push(parameter); } } /** debug implementation: pop from stack: forget last {@link #debugPush(String)}. */ protected void debugPop() { if (debugStack != null) { debugStack.pop(); } } /** show debug stacktrace, if {@link StringTemplateEngine#sedDebugEnabled(boolean)} is set to true. */ protected String getDebugStackTrace() { StringBuilder result = new StringBuilder(); if (debugStack != null) { ListIterator iter = debugStack.listIterator(); if (iter.hasNext()) { result.append(" > ").append(iter.next()); } } return result.toString(); } /** get last error message. Error is cleared after reading message. */ public String getErrors() { if (errors == null) return null; final String result = errors.toString(); errors.setLength(0); return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy