package edu.sc.seis.sod.status; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import edu.sc.seis.sod.ConfigurationException; public abstract class Template{ /** *returns an object of the template type that this class uses, and returns * the passed in text when the getResult method of that template type is * called */ protected abstract Object textTemplate(final String text); /**if this class has an template for this tag, it creates it using the * passed in element and returns it. Otherwise it should return * the superclass implementation of the getCommonTemplate method. Though no harm will come * from merely returning null, they won't benefit from the wisdom and extra * tags provided by their elder classes. */ protected Object getTemplate(String tag, Element el) throws ConfigurationException { return getCommonTemplate(tag, el); } /** actually return Templates for common tags. This is to allow subclasses to * avoid throwing ConfigurationException if it can never really happen. **/ protected Object getCommonTemplate(String tag, Element el) { if(tag.equals("runName")){ return new RunNameTemplate(); } else if(tag.equals("startTime")){ return new StartTimeTemplate(); } else if(tag.equals("now")){ return new NowTemplate();} else if(tag.equals("configFileLoc")){ return textTemplate(IndexTemplate.getCopiedConfigFileLocation()); }else if(tag.equals("htmlConfigFileLoc")){ return textTemplate(IndexTemplate.getHtmlConfigFileName()); }else if(tag.equals("errorCount")){ return new ErrorCountTemplate(); } return null; } protected void parse(Element el) throws ConfigurationException { parse(el, false); } /** @param trim Removes all whitespace from TEXT_NODEs. * */ protected void parse(Element el, boolean trim) throws ConfigurationException { parse(el.getChildNodes(), trim); if(!builtUpText.equals("")) templates.add(textTemplate(builtUpText)); } private void parse(NodeList nl) throws ConfigurationException { parse(nl, false); } /** @param trim Removes all whitespace from TEXT_NODEs. * */ private void parse(NodeList nl, boolean trim) throws ConfigurationException { for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); if(n.getNodeType() == Node.TEXT_NODE) { String s = n.getNodeValue(); if (trim) { s = s.trim(); // \s means all whitespace characters s = s.replaceAll("\\s", ""); } addString(s); } else if (n.getNodeType() == Node.COMMENT_NODE) { // skip it } else{ String name = n.getNodeName(); if(name.equals("attribute")) continue; Object template = getTemplate(name, (Element)n); if(template != null) addTemplate(template); else{ addString("<" + name); int numAttr = addAttributes(n); if(n.getChildNodes().getLength() - numAttr == 0) addString("/>"); else{ addString(">"); parse(n.getChildNodes()); addString("</" + name + ">"); } } } } } private void addTemplate(Object template){ if(!builtUpText.equals("")) templates.add(textTemplate(builtUpText)); templates.add(template); builtUpText = ""; } private void addString(String text){ builtUpText += text; } private String builtUpText = ""; private int addAttributes(Node n) throws ConfigurationException { addString(getAttrString(n)); int numAttr = 0; for (int i = 0; i < n.getChildNodes().getLength() && childName(i, n).equals("attribute"); i++) { Element attr = (Element)n.getChildNodes().item(i); addString(" " + attr.getAttribute("name") + "=\""); parse(attr.getChildNodes()); addString("\""); numAttr++; } return numAttr; } private static String childName(int i, Node n){ return n.getChildNodes().item(i).getNodeName(); } private String getAttrString(Node n){ String result = ""; NamedNodeMap attr = n.getAttributes(); for (int i = 0; i < attr.getLength(); i++) { result += " " + attr.item(i).getNodeName(); result += "=\"" + attr.item(i).getNodeValue() + "\""; } return result; } public void setUp(){} protected List templates = new ArrayList(); private static Logger logger = LoggerFactory.getLogger(Template.class); }