/*
* Copyright 2012-2015 org.opencloudb.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* (created at 2012-6-15)
*/
package org.opencloudb.config.loader.xml;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.opencloudb.config.model.ClusterConfig;
import org.opencloudb.config.model.QuarantineConfig;
import org.opencloudb.config.model.SystemConfig;
import org.opencloudb.config.model.UserConfig;
import org.opencloudb.config.util.ConfigException;
import org.opencloudb.config.util.ConfigUtil;
import org.opencloudb.config.util.ParameterMapping;
import org.opencloudb.util.SplitUtil;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author mycat
*/
@SuppressWarnings("unchecked")
public class XMLServerLoader {
private final SystemConfig system;
private final Map<String, UserConfig> users;
private final QuarantineConfig quarantine;
private ClusterConfig cluster;
public XMLServerLoader() {
this.system = new SystemConfig();
this.users = new HashMap<String, UserConfig>();
this.quarantine = new QuarantineConfig();
this.load();
}
public SystemConfig getSystem() {
return system;
}
public Map<String, UserConfig> getUsers() {
return (Map<String, UserConfig>) (users.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(users));
}
public QuarantineConfig getQuarantine() {
return quarantine;
}
public ClusterConfig getCluster() {
return cluster;
}
private void load() {
InputStream dtd = null;
InputStream xml = null;
try {
dtd = XMLServerLoader.class.getResourceAsStream("/server.dtd");
xml = XMLServerLoader.class.getResourceAsStream("/server.xml");
Element root = ConfigUtil.getDocument(dtd, xml).getDocumentElement();
loadSystem(root);
loadUsers(root);
this.cluster = new ClusterConfig(root, system.getServerPort());
loadQuarantine(root);
} catch (ConfigException e) {
throw e;
} catch (Throwable e) {
throw new ConfigException(e);
} finally {
if (dtd != null) {
try {
dtd.close();
} catch (IOException e) {
}
}
if (xml != null) {
try {
xml.close();
} catch (IOException e) {
}
}
}
}
private void loadQuarantine(Element root) {
NodeList list = root.getElementsByTagName("host");
for (int i = 0, n = list.getLength(); i < n; i++) {
Node node = list.item(i);
if (node instanceof Element) {
Element e = (Element) node;
String host = e.getAttribute("name").trim();
if (quarantine.getHosts().containsKey(host)) {
throw new ConfigException("host duplicated : " + host);
}
Map<String, Object> props = ConfigUtil.loadElements(e);
String[] users = SplitUtil.split((String) props.get("user"), ',', true);
HashSet<String> set = new HashSet<String>();
if (null != users) {
for (String user : users) {
UserConfig uc = this.users.get(user);
if (null == uc) {
throw new ConfigException("[user: " + user + "] doesn't exist in [host: " + host + "]");
}
if (null == uc.getSchemas() || uc.getSchemas().size() == 0) {
throw new ConfigException("[host: " + host + "] contains one root privileges user: " + user);
}
if (set.contains(user)) {
throw new ConfigException("[host: " + host + "] contains duplicate user: " + user);
} else {
set.add(user);
}
}
}
quarantine.getHosts().put(host, set);
}
}
}
private void loadUsers(Element root) {
NodeList list = root.getElementsByTagName("user");
for (int i = 0, n = list.getLength(); i < n; i++) {
Node node = list.item(i);
if (node instanceof Element) {
Element e = (Element) node;
String name = e.getAttribute("name");
UserConfig user = new UserConfig();
user.setName(name);
Map<String, Object> props = ConfigUtil.loadElements(e);
user.setPassword((String) props.get("password"));
String schemas = (String) props.get("schemas");
if (schemas != null) {
String[] strArray = SplitUtil.split(schemas, ',', true);
user.setSchemas(new HashSet<String>(Arrays.asList(strArray)));
}
if (users.containsKey(name)) {
throw new ConfigException("user " + name + " duplicated!");
}
users.put(name, user);
}
}
}
private void loadSystem(Element root) throws IllegalAccessException, InvocationTargetException {
NodeList list = root.getElementsByTagName("system");
for (int i = 0, n = list.getLength(); i < n; i++) {
Node node = list.item(i);
if (node instanceof Element) {
Map<String, Object> props = ConfigUtil.loadElements((Element) node);
ParameterMapping.mapping(system, props);
}
}
}
}