/* * Copyright (C) 2005-2012 NAUMEN. All rights reserved. * * This file may be distributed and/or modified under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation and appearing in the file LICENSE.GPL included in the * packaging of this file. * */ package ru.naumen.servacc.config2; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import ru.naumen.servacc.config2.i.IConfig; import ru.naumen.servacc.config2.i.IConfigItem; import ru.naumen.servacc.util.Util; public class Config implements IConfig { public static final String GROUP_NODE_NAME = "Group"; public static final String GROUP_ATTR_NAME = "name"; public static final String GROUP_ATTR_COMMENT = "comment"; public static final String ACCOUNT_NODE_NAME = "Account"; public static final String ACCOUNT_ATTR_ID = "id"; public static final String ACCOUNT_ATTR_TYPE = "type"; public static final String ACCOUNT_ATTR_NAME = "name"; public static final String ACCOUNT_ATTR_COMMENT = "comment"; public static final String ACCOUNT_PARAM_THROUGH = "through"; public static final String PARAM_NODE_NAME = "Param"; public static final String PARAM_ATTR_NAME = "name"; public static final String PARAM_ATTR_VALUE = "value"; private Group root; public Config(InputStream stream) throws Exception { root = new Parser(stream).parseConfig(); } public List<IConfigItem> getChildren() { return root.getChildren(); } private class Parser { private InputStream stream; private Group rootGroup; private Map<String, Account> accounts; private Map<Account, String> needsThrough; Parser(InputStream stream) { this.stream = stream; } public Group parseConfig() throws Exception { rootGroup = new Group(); accounts = new HashMap<>(); needsThrough = new HashMap<>(); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse(stream); Node rootNode = doc.getDocumentElement(); recursiveParseGroup(rootGroup, rootNode); // update 'through' references for (Entry<Account, String> e : needsThrough.entrySet()) { e.getKey().setThrough(accounts.get(e.getValue())); } return rootGroup; } private void recursiveParseGroup(Group group, Node rootNode) { NodeList nodes = rootNode.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); String name = node.getNodeName(); if (node.getNodeType() != Node.ELEMENT_NODE) { continue; } if (GROUP_NODE_NAME.equals(name)) { Group subGroup = parseGroup(node); group.getChildren().add(subGroup); recursiveParseGroup(subGroup, node); } else if (ACCOUNT_NODE_NAME.equals(name)) { group.getChildren().add(parseAccount(node)); } } } private Group parseGroup(Node node) { String name = getAttribute(node, GROUP_ATTR_NAME, ""); String comment = getAttribute(node, GROUP_ATTR_COMMENT, ""); return new Group(name, comment); } private Account parseAccount(Node node) { String id = getAttribute(node, ACCOUNT_ATTR_ID); String type = getAttribute(node, ACCOUNT_ATTR_TYPE, ""); String name = getAttribute(node, ACCOUNT_ATTR_NAME, ""); String comment = getAttribute(node, ACCOUNT_ATTR_COMMENT, ""); HashMap<String, String> params = new HashMap<>(); NodeList nodes = node.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node subNode = nodes.item(i); if (subNode.getNodeType() != Node.ELEMENT_NODE) { continue; } if (PARAM_NODE_NAME.equals(subNode.getNodeName())) { String pName = getAttribute(subNode, PARAM_ATTR_NAME); String pValue = getAttribute(subNode, PARAM_ATTR_VALUE); if (pName != null && pValue != null) { params.put(pName, pValue); } } } Account account; if (SSHAccount.SSHACCOUNT_TYPE.equalsIgnoreCase(type)) { account = new SSHAccount(); } else if (HTTPAccount.HTTPACCOUNT_TYPE.equalsIgnoreCase(type)) { account = new HTTPAccount(); } else { account = new Account(); } account.setId(id); account.setType(type); account.setName(name); account.setComment(comment); account.setParams(params); accounts.put(account.getId(), account); String through = account.getParams().get(ACCOUNT_PARAM_THROUGH); if (!Util.isEmptyOrNull(through)) { needsThrough.put(account, through); } return account; } private String getAttribute(Node node, String name, String defValue) { Node attrNode = node.getAttributes().getNamedItem(name); if (attrNode != null) { return attrNode.getNodeValue(); } return defValue; } private String getAttribute(Node node, String name) { return getAttribute(node, name, null); } } }