001: package org.igfay.jfig;
002:
003: import java.io.IOException;
004:
005: import javax.xml.parsers.DocumentBuilder;
006: import javax.xml.parsers.ParserConfigurationException;
007:
008: import org.apache.log4j.Logger;
009: import org.igfay.util.PrettyPrinter;
010: import org.w3c.dom.Document;
011: import org.w3c.dom.Element;
012: import org.w3c.dom.NodeList;
013: import org.xml.sax.InputSource;
014: import org.xml.sax.SAXException;
015:
016: /**
017: * @author conrad4
018: *
019: * Parse configuration files that are in XML format.
020: */
021: public class XMLJFigParser extends JFigParser {
022:
023: private static Logger logger = Logger
024: .getLogger(XMLJFigParser.class);
025:
026: public XMLJFigParser(JFig config, JFigLocatorIF jfigLocator) {
027: super (config, jfigLocator);
028: }
029:
030: /**
031: * Process XML Configuration file
032: */
033: protected boolean processConfig() throws JFigException {
034: logger.debug("Process file " + getConfigFileName());
035: Element element = null;
036: try {
037: element = parse();
038: } catch (XMLParseException e) {
039: throw new JFigException(e.getMessage()
040: + " Requested File: " + getConfigFileName());
041: }
042: if (logger.isDebugEnabled()) {
043: logger.debug("element\n");
044: PrettyPrinter.printNode(element);
045: logger.debug("process includes");
046: }
047: processIncludes(element);
048:
049: logger.debug("process sections");
050: processSections(element);
051: return true;
052: }
053:
054: /**
055: * @author conrad4
056: *
057: * For each include element, process the included configuration file
058: */
059: protected void processIncludes(Element element)
060: throws JFigException {
061: NodeList nodeList = element
062: .getElementsByTagName(JFigConstants.INCLUDE);
063: for (int i = 0; i < nodeList.getLength(); i++) {
064: Element node = (Element) nodeList.item(i);
065: String fileName = node.getAttribute(JFigConstants.NAME);
066: logger.debug("fileName " + fileName);
067: if (isNewFile(fileName)) {
068: getAllConfigFiles().put(fileName, fileName);
069: setConfigLocation(node);
070: getJFigLocator().setConfigFileName(fileName);
071: JFigParser parser = new XMLJFigParser(getConfig(),
072: getJFigLocator());
073: logger.debug("call parser to process " + fileName);
074: parser.processConfig();
075: }
076:
077: }
078: }
079:
080: /**
081: * Get the configLocation of the included config file.
082: * If something is specified, reset.
083: * If nothing is specified, leave it alone.
084: * Note: Subsequent includes will use the last value set.
085: * It might be better to have them use the original value.
086: * However, it could get very complicated if one is mixing locations.
087: *
088: *
089: * @param element
090: * @return
091: * @throws JFigException
092: */
093: private String setConfigLocation(Element element)
094: throws JFigException {
095: String locationValue = element.getAttribute("location");
096: if (locationValue != null && locationValue.length() > 0) {
097: getJFigLocator().setConfigLocation(locationValue);
098: }
099: logger.debug("~ locationValue -" + locationValue + "-");
100: return locationValue;
101: }
102:
103: /**
104: * For each section element, find the entry elements
105: */
106: protected void processSections(Element element) {
107: NodeList sectionNodeList = element
108: .getElementsByTagName(JFigConstants.SECTION);
109: for (int i = 0; i < sectionNodeList.getLength(); i++) {
110: Element sectionNode = (Element) sectionNodeList.item(i);
111: String sectionString = sectionNode
112: .getAttribute(JFigConstants.NAME);
113: getConfigDictionary().getSectionNamed(sectionString, true);
114:
115: processEntries(sectionNode, sectionString);
116: }
117: }
118:
119: /**
120: * For each entry element, process key value pair
121: */
122: protected void processEntries(Element sectionNode,
123: String sectionString) {
124:
125: NodeList entryNodeList = sectionNode
126: .getElementsByTagName(JFigConstants.ENTRY);
127: for (int j = 0; j < entryNodeList.getLength(); j++) {
128: Element entryNode = (Element) entryNodeList.item(j);
129: String keyString = entryNode
130: .getAttribute(JFigConstants.KEY);
131: // If not value attribute is supplied, make it null
132: String valueString = null;
133: if (entryNode.getAttributeNode(JFigConstants.VALUE) != null) {
134: valueString = entryNode
135: .getAttribute(JFigConstants.VALUE);
136: }
137: getConfigDictionary().addKeyValueToSection(sectionString,
138: keyString, valueString);
139: }
140: }
141:
142: /**
143: * Ensure same file is not processed multiple times
144: *
145: * @param fileName
146: * @return boolean
147: */
148: protected boolean isNewFile(String fileName) {
149: boolean isNewFile = getAllConfigFiles().get(fileName) == null;
150: logger.debug("" + isNewFile);
151: return isNewFile;
152: }
153:
154: /**
155: * Parse the config file into an xml document
156: * @return
157: * @throws JFigException
158: * @throws XMLParseException
159: */
160: protected Element parse() throws JFigException, XMLParseException {
161: InputSource isrc = new InputSource(getJFigLocator()
162: .getInputStream());
163: logger.info("Process file " + getConfigFileName());
164:
165: javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory
166: .newInstance();
167: Document document = null;
168: try {
169: DocumentBuilder db = dbf.newDocumentBuilder();
170: document = db.parse(isrc);
171: } catch (ParserConfigurationException e) {
172: throw new XMLParseException(e.getMessage());
173: } catch (SAXException e) {
174: throw new XMLParseException(e);
175: } catch (IOException e) {
176:
177: throw new XMLParseException(e.getMessage());
178: }
179: return document.getDocumentElement();
180: }
181:
182: }
|