/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.web.dcui; import java.io.PrintStream; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import divconq.util.StringUtil; import divconq.web.WebContext; abstract public class Node { // @[a-zA-Z0-9_\\-,:/]+@ public static Pattern macropatten = Pattern.compile("@\\S+?@", Pattern.MULTILINE); protected boolean blockindent = false; protected Element parent = null; protected Map<String,String> valueparams = null; protected Map<String,Nodes> complexparams = null; public boolean getBlockIndent() { return this.blockindent; } public void setBlockIndent(boolean value) { this.blockindent = value; } public Fragment getViewRoot() { if (this.parent == null) { if (this instanceof Fragment) return (Fragment) this; return null; } return this.parent.getViewRoot(); } public Fragment getPartRoot() { if (this instanceof Fragment) return (Fragment) this; if (this.parent == null) return null; return this.parent.getPartRoot(); } public Element getParent() { return this.parent; } public void setParent(Element v) { this.parent = v; } public void setParams(Map<String, String> params) { this.valueparams = params; } public void addParams(String... params) { if (this.valueparams == null) this.valueparams = new HashMap<String, String>(); for (int i = 1; i < params.length; i += 2) this.valueparams.put(params[i-1], params[i]); } public void putParam(String name, String value) { if (this.valueparams == null) this.valueparams = new HashMap<String, String>(); this.valueparams.put(name, value); } public boolean hasParam(WebContext ctx, String name) { if ((this.valueparams != null) && this.valueparams.containsKey(name)) return true; if (this.parent != null) return this.parent.hasParam(ctx, name); return ctx.hasInternalParam(name); } public String getParam(WebContext ctx, String name) { if ((this.valueparams != null) && this.valueparams.containsKey(name)) return this.valueparams.get(name); if (this.parent != null) return this.parent.getParam(ctx, name); return ctx.getInternalParam(name); } public void setComplexParams(Map<String, Nodes> params) { this.complexparams = params; } public void putParam(String name, Nodes list) { if (this.complexparams == null) this.complexparams = new HashMap<String, Nodes>(); this.complexparams.put(name, list); } public Nodes getComplexParam(String name) { if ((this.complexparams != null) && this.complexparams.containsKey(name)) return this.complexparams.get(name); if (this.parent != null) return this.parent.getComplexParam(name); return null; } public String expandMacro(WebContext ctx, String value) { if (StringUtil.isEmpty(value)) return null; boolean checkmatches = true; while (checkmatches) { checkmatches = false; Matcher m = Node.macropatten.matcher(value); while (m.find()) { String grp = m.group(); String macro = grp.substring(1, grp.length() - 1); String val = null; // params on this tree if (macro.startsWith("val|")) val = this.getParam(ctx, macro.substring(4)); else val = ctx.expandMacro(macro); // if any of these, then replace and check (expand) again if (val != null) { value = value.replace(grp, val); checkmatches = true; } } } return value; } public abstract void doBuild(WebContext ctx); public void stream(WebContext ctx, PrintStream strm) { this.stream(ctx, strm, "", false, false); } public abstract void stream(WebContext ctx, PrintStream strm, String indent, boolean firstchild, boolean fromblock); public void print(WebContext ctx, PrintStream strm, String indent, boolean newline, String copy) { strm.print(indent + copy); if (newline) strm.println(); } public boolean writeDynamic(PrintStream buffer, String tabs, boolean first) { return false; } static public void writeDynamicJsString(PrintStream buffer, String s) { final int len = s.length(); for(int i = 0; i < len; i++) { char ch = s.charAt(i); switch(ch){ case '\'': buffer.print("\\\'"); break; case '\\': buffer.print("\\\\"); break; case '\b': buffer.print("\\b"); break; case '\f': buffer.print("\\f"); break; case '\n': buffer.print("\\n"); break; case '\r': buffer.print("\\r"); break; case '\t': buffer.print("\\t"); break; case '/': buffer.print("\\/"); break; default: //Reference: http://www.unicode.org/versions/Unicode5.1.0/ if((ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')) { String ss = Integer.toHexString(ch); buffer.print("\\u"); for(int k = 0; k < 4 - ss.length(); k++) buffer.print('0'); buffer.print(ss.toUpperCase()); } else buffer.print(ch); } }//for } }