package com.intrbiz.bergamot.config; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Stack; import java.util.TreeMap; import javax.xml.bind.JAXBException; import com.intrbiz.bergamot.config.model.BergamotCfg; import com.intrbiz.bergamot.config.model.TemplatedObjectCfg; import com.intrbiz.bergamot.config.validator.ValidatedBergamotConfiguration; public class BergamotConfigReader { private Map<String, BergamotCfg> configurations = new TreeMap<String, BergamotCfg>(); private Stack<File> toParse = new Stack<File>(); private String overrideSiteName; public BergamotConfigReader() { super(); } public BergamotConfigReader includeDir(File dir) { Stack<File> work = new Stack<File>(); work.push(dir); while (!work.isEmpty()) { File f = work.pop(); if (f.isFile() && f.getName().endsWith(".xml")) { this.toParse.push(f); } else if (f.isDirectory()) { for (File c : f.listFiles()) { work.push(c); } } } return this; } public BergamotConfigReader inject(BergamotCfg configuration) { if (this.overrideSiteName != null) configuration.setSite(this.overrideSiteName); // merge the config this.merge(configuration); return this; } public BergamotConfigReader overrideSiteName(String siteName) { this.overrideSiteName = siteName; return this; } public Collection<ValidatedBergamotConfiguration> build() { this.parse(); // validate List<ValidatedBergamotConfiguration> validated = new LinkedList<ValidatedBergamotConfiguration>(); for (BergamotCfg cfg : this.configurations.values()) { validated.add(cfg.validate()); } return validated; } private void parse() { while (! this.toParse.isEmpty()) { File file = this.toParse.pop(); try (FileInputStream in = new FileInputStream(file)) { BergamotCfg cfg = BergamotCfg.read(BergamotCfg.class, in); // set the file the object was loaded from for (List<? extends TemplatedObjectCfg<?>> objects : cfg.getAllObjects()) { for (TemplatedObjectCfg<?> object : objects) { object.setLoadedFrom(file); } } // forcefully override site name if (this.overrideSiteName != null) cfg.setSite(this.overrideSiteName); // merge together this.merge(cfg); } catch (IOException | JAXBException e) { System.err.println("Failed to parse configuration file: " + file.getAbsolutePath()); e.printStackTrace(); } } } private void merge(BergamotCfg cfg) { BergamotCfg existing = this.configurations.get(cfg.getSite()); if (existing == null) { this.configurations.put(cfg.getSite(), cfg); } else { existing.mergeIn(cfg); } } public Collection<BergamotCfg> getConfigurations() { return this.configurations.values(); } }