com.github.narcissujsk.openstackjsk.openstack.heat.utils.Template Maven / Gradle / Ivy
The newest version!
package com.github.narcissujsk.openstackjsk.openstack.heat.utils;
import com.fasterxml.jackson.core.JsonParseException;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.github.narcissujsk.openstackjsk.openstack.heat.utils.TemplateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Template {
private static final Logger LOG = LoggerFactory.getLogger(Template.class);
// template Resource is used for represent the template file or template URL
private String tplContent;
private Map files = new HashMap();
private URL baseUrl;
private final static String GET_FILE = "get_file";
public Template(URL templateRes) throws JsonParseException, IOException{
setTplContent(Resources.toString(templateRes, Charsets.UTF_8));
baseUrl = TemplateUtils.baseUrl(templateRes.toString());
getFileContents();
}
public Template(String templateLoc)
throws JsonParseException, MalformedURLException,
UnsupportedEncodingException, IOException, URISyntaxException {
this(TemplateUtils.normaliseFilePathToUrl(templateLoc));
}
/*
* Processing the template file to find the "get_file" tag
* Save the file name(absolute path) with file content in the files map
*/
private void getFileContents() {
Yaml yaml = new Yaml();
@SuppressWarnings("unchecked")
Map content = (Map) yaml.load(getTplContent());
try {
resolveTemplateGetFiles(content);
resolveTemplateType(content);
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
}
private void resolveTemplateType(Map map) throws MalformedURLException, IOException {
for(Object key : map.keySet()) {
// Ignore if the key is not string. Actually not happening
if(!(key instanceof String)) {
continue;
}
String skey = (String) key;
Object value = map.get(skey);
if(value instanceof String) {
String valueInString = (String) value;
//Processing the nested template
if(isTemplate(skey, valueInString)) {
try {
final String templateName = valueInString;
final URL fullTemplateName = TemplateUtils.normaliseFilePathToUrl(baseUrl.toString(), templateName);
if(! files.containsKey(templateName)) {
final Template tpl = new Template(fullTemplateName);
files.put(templateName, tpl.getTplContent());
files.putAll(tpl.getFiles());
}
} catch (URISyntaxException e) {
LOG.error(e.getMessage(), e);
}
}
}
if (value instanceof Map){
resolveTemplateType((Map)value);
} else if (value instanceof List) {
for (Object item : (List) value) {
if (item instanceof Map) {
resolveTemplateType((Map) item);
}
}
}
}
}
private void resolveTemplateGetFiles(Map map) throws IOException {
for(Object key : map.keySet()){
// Ignore if the key is not string. Actually not happening
if(!(key instanceof String)) {
continue;
}
String skey = (String) key;
Object value = map.get(skey);
if(isGetFile(skey)) {
//if key="get_file", the value is the filename
addToFiles((String)value);
continue;
}
Object subMap = map.get(skey);
if (subMap instanceof Map){
resolveTemplateGetFiles((Map)subMap);
} else if (subMap instanceof List) {
for (Object item : (List) subMap) {
if (item instanceof Map) {
resolveTemplateGetFiles((Map) item);
}
}
}
}
}
private void addToFiles(String filename) throws IOException {
if(! files.containsKey(filename)) {
if (filename.startsWith("/")){
files.put(filename, TemplateUtils.readToString(filename));
} else {
files.put(filename, TemplateUtils.readToString(baseUrl + filename));
}
}
}
private boolean isGetFile(String tag) {
return tag.equals(GET_FILE);
}
private boolean isTemplate(String key, String value) {
if (! key.equals("type")) {
return false;
}
if (value.endsWith(".yaml") || value.endsWith(".template")) {
return true;
} else {
return false;
}
}
public String getTplContent() {
return tplContent;
}
public void setTplContent(String tplContent) {
this.tplContent = tplContent;
}
public Map getFiles() {
return files;
}
public void setFiles(Map files) {
this.files = files;
}
}