001    package org.shiftone.jrat.core.config;
002    
003    
004    import org.shiftone.jrat.core.JRatException;
005    import org.shiftone.jrat.core.criteria.MatcherMethodCriteria;
006    import org.shiftone.jrat.util.Assert;
007    import org.shiftone.jrat.util.PropertyUtil;
008    import org.shiftone.jrat.util.log.Logger;
009    import org.w3c.dom.Document;
010    import org.w3c.dom.Element;
011    import org.w3c.dom.NodeList;
012    
013    import javax.xml.parsers.DocumentBuilder;
014    import javax.xml.parsers.DocumentBuilderFactory;
015    import java.io.InputStream;
016    import java.util.HashMap;
017    import java.util.Map;
018    
019    /**
020     * @author jeff@shiftone.org (Jeff Drost)
021     */
022    public class ConfigurationParser {
023    
024        private static final Logger LOG = Logger.getLogger(ConfigurationParser.class);
025    
026        public static Configuration parse(InputStream in) {
027    
028            ConfigurationParser parser = new ConfigurationParser();
029            Configuration configuration = new Configuration();
030            parser.parse(configuration, in);
031            return configuration;
032        }
033    
034        public void parse(Configuration configuration, InputStream in) {
035    
036            LOG.info("parsing configuration...");
037    
038            try {
039    
040                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
041                DocumentBuilder builder = dbf.newDocumentBuilder();
042                Document document = builder.parse(in);
043                processJrat(configuration, document.getDocumentElement());
044    
045            } catch (Exception e) {
046    
047                throw new JRatException("failed to parse configuration", e);
048    
049            }
050        }
051    
052    
053        private void processJrat(Configuration configuration, Element jratElement) {
054    
055            Assert.assertNotNull(jratElement);
056    
057            NodeList settings = jratElement.getElementsByTagName("settings");
058            for (int i = 0; i < settings.getLength(); i++) {
059                processSettings(configuration, (Element) settings.item(i));
060            }
061    
062            NodeList handlers = jratElement.getElementsByTagName("profile");
063            for (int i = 0; i < handlers.getLength(); i++) {
064                processProfile(configuration.createProfile(), (Element) handlers.item(i));
065            }
066    
067    
068        }
069    
070        private void processSettings(Configuration configuration, Element settingsElement) {
071    
072            Assert.assertNotNull(settingsElement);
073    
074            NodeList properties = settingsElement.getElementsByTagName("property");
075    
076            Map map = new HashMap();
077    
078            for (int i = 0; i < properties.getLength(); i++) {
079                Element propertyElement = (Element) properties.item(i);
080                map.put(propertyElement.getAttribute("name"),
081                        propertyElement.getAttribute("value"));
082            }
083    
084            PropertyUtil.setProperties(configuration.getSettings(), map);
085        }
086    
087        private void processProfile(Profile profile, Element profileElement) {
088    
089            Assert.assertNotNull(profileElement);
090    
091            profile.setName(profileElement.getAttribute("name"));
092    
093            NodeList includes = profileElement.getElementsByTagName("include");
094            for (int i = 0; i < includes.getLength(); i++) {
095                processCriteria(profile.createInclude(), (Element) includes.item(i));
096            }
097    
098            NodeList excludes = profileElement.getElementsByTagName("exclude");
099            for (int i = 0; i < excludes.getLength(); i++) {
100                processCriteria(profile.createExclude(), (Element) excludes.item(i));
101            }
102    
103            NodeList handlers = profileElement.getElementsByTagName("handler");
104            for (int i = 0; i < handlers.getLength(); i++) {
105                processHandler(profile.createFactory(), (Element) handlers.item(i));
106            }
107        }
108    
109        private void processHandler(Handler handler, Element factoryElement) {
110    
111            // <handler factory="org.shiftone.jrat.provider.tree.TreeMethodHandlerFactory">
112    
113            handler.setClassName(factoryElement.getAttribute("factory"));
114            NodeList properties = factoryElement.getElementsByTagName("property");
115    
116            for (int i = 0; i < properties.getLength(); i++) {
117    
118                Element property = (Element) properties.item(i);
119                String name = nvl(property.getAttribute("name"));
120                String value = nvl(property.getAttribute("value"));
121                Assert.assertNotNull("name", name);
122                handler.getProperties().put(name, value);
123    
124            }
125        }
126    
127        private void processCriteria(MatcherMethodCriteria criteria, Element criteriaElement) {
128    
129            criteria.setClassName(nvl(criteriaElement.getAttribute("className")));
130            criteria.setMethodName(nvl(criteriaElement.getAttribute("methodName")));
131            criteria.setSignature(nvl(criteriaElement.getAttribute("signature")));
132    
133            LOG.info("processCriteria " + criteria);
134        }
135    
136        private String nvl(String s) {
137            if (s.trim().length() == 0) {
138                return null;
139            } else {
140                return s;
141            }
142        }
143    
144    
145    }