package org.molgenis.generator; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.molgenis.compute.ComputeParameter; import org.molgenis.util.Pair; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.*; /** * Created by IntelliJ IDEA. * User: georgebyelas * Date: 26/04/2012 * Time: 13:17 * To change this template use File | Settings | File Templates. */ //processing freemarker templates in java - misuse of freemarker with folding public class FoldingParser { private static String BAD = "The problematic instruction:"; //is table (worksheet) folded private boolean isTableFoldered = false; //values which are lists in the worksheet private Vector<String> vecListsInTable = null; private Collection<ComputeParameter> parameters = null; private boolean isList; // public String parseTemplateLineByHand(String parTemplate, Hashtable<String, Object> line, int i, Hashtable<String, String> simpleValues) { Hashtable<String, String> values = new Hashtable<String, String>(); Enumeration ekeys = line.keys(); while (ekeys.hasMoreElements()) { String ekey = (String) ekeys.nextElement(); String value; if (line.get(ekey) instanceof Collection<?>) { List<String> eValue = (List<String>) line.get(ekey); value = eValue.get(i); } else value = (String) line.get(ekey); values.put(ekey, value); } values.putAll(simpleValues); String result = doByHand(parTemplate, values); return result; } //we try to process freemarker with freemarker //if failed - do it by hand public String doByHand(String parTemplate, Hashtable<String, String> values) { String result = weaveFreemarker(parTemplate, values); if (result.contains(BAD)) { Enumeration ekeys = values.keys(); while (ekeys.hasMoreElements()) { String ekey = (String) ekeys.nextElement(); String value = (String) values.get(ekey); String freemarkerKey = "${" + ekey + "}"; if (parTemplate.contains(freemarkerKey)) parTemplate = parTemplate.replace(freemarkerKey, value); } return parTemplate; } return result; } public int getFolderedLineSize(Hashtable<String, Object> line) { //we need to find maximum folded values number int max = 1; Enumeration ekeys = line.keys(); while (ekeys.hasMoreElements()) { String ekey = (String) ekeys.nextElement(); Object eValue = line.get(ekey); if (eValue instanceof Collection<?>) { List<String> l = (List<String>) eValue; if (l.size() > max) max = l.size(); } } return max; } public String parseTemplateOneLineByHand(String parTemplate, Hashtable<String, Object> line, Hashtable<String, String> simpleValues) { Hashtable<String, String> values = new Hashtable<String, String>(); Enumeration ekeys = line.keys(); while (ekeys.hasMoreElements()) { String ekey = (String) ekeys.nextElement(); String value = (String) line.get(ekey); values.put(ekey, value); } values.putAll(simpleValues); String result = doByHand(parTemplate, values); return result; } public boolean isValueSimple(Pair<String, Object> value) { Object v = value.getB(); if (v instanceof Collection<?>) { List<String> strings = (List<String>) v; for (String str : strings) { if (str.contains("${")) return false; } } else { String str = (String) value.getB(); if (str.contains("${")) return false; } return true; } //obsolete used only with old generic job generator public boolean isDirectlyDependOnWorksheet(ComputeParameter parameter, List<Hashtable> table) { Hashtable row = table.get(0); Enumeration rowKeys = row.keys(); while (rowKeys.hasMoreElements()) { String ekey = (String) rowKeys.nextElement(); ekey = "${" + ekey + "}"; String parTemplate = parameter.getDefaultValue(); if (parTemplate.contains(ekey)) return true; } return false; } public void evaluateTable(List<Hashtable> table) { vecListsInTable = new Vector<String>(); Hashtable<String, Object> line = table.get(0); Enumeration ekeys = line.keys(); while (ekeys.hasMoreElements()) { String ekey = (String) ekeys.nextElement(); Object eValue = line.get(ekey); if (eValue instanceof Collection<?>) { vecListsInTable.addElement(ekey); isTableFoldered = true; } } } public void setParametersList(Collection<ComputeParameter> parameters) { this.parameters = parameters; } //recursive checking if parameter depends on worksheet public void checkIsList(String parTemplate) { if (!isTableFoldered) setNotList(); else { int open_pos = 0; while (open_pos > -1) { open_pos = parTemplate.indexOf("${", open_pos); if (open_pos > -1) { int close_pos = parTemplate.indexOf("}", open_pos); if (close_pos > -1) { String strParameter = parTemplate.substring(open_pos + 2, close_pos); ComputeParameter par = findParameter(strParameter); if(par != null) { boolean isFolded = getIsFolded(par.getName()); if(isFolded) setIsList(); String template = par.getDefaultValue(); if(template != null) { checkIsList(template); } } open_pos = close_pos; } } } } } public void setNotList() { this.isList = false; } private boolean getIsFolded(String name) { for(String n : vecListsInTable) { if(n.equalsIgnoreCase(name)) return true; } return false; } public String weaveFreemarker(String strTemplate, Hashtable<String, String> values) { Configuration cfg = new Configuration(); //cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); Template t = null; StringWriter out = new StringWriter(); try { t = new Template("name", new StringReader(strTemplate), cfg); t.process(values, out); } catch (TemplateException e) { //e.printStackTrace(); } catch (IOException e) { //e.printStackTrace(); } return out.toString(); } private ComputeParameter findParameter(String s) { Iterator<ComputeParameter> itr = parameters.iterator(); while (itr.hasNext()) { ComputeParameter par = itr.next(); String name = par.getName(); if (s.equalsIgnoreCase(name)) return par; } return null; } public void setIsList() { this.isList = true; } public boolean getIsList() { return isList; } }