XMLHostDAO.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
* tags. See the COPYRIGHT.txt in the distribution for a full listing of
* individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.openr66.dao.xml;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.waarp.common.utility.ParametersChecker;
import org.waarp.common.utility.WaarpStringUtils;
import org.waarp.openr66.dao.Filter;
import org.waarp.openr66.dao.HostDAO;
import org.waarp.openr66.dao.exception.DAOConnectionException;
import org.waarp.openr66.dao.exception.DAONoDataException;
import org.waarp.openr66.pojo.Host;
import org.waarp.openr66.protocol.configuration.Configuration;
import org.xml.sax.SAXException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import static org.waarp.openr66.dao.DAOFactory.*;
import static org.waarp.openr66.dao.database.DBHostDAO.*;
public class XMLHostDAO implements HostDAO {
/**
* HashTable in case of lack of database
*/
private static final ConcurrentHashMap<String, Host> dbR66HostAuthHashMap =
new ConcurrentHashMap<String, Host>();
private static final String XML_SELECT = "/authent/entry[hostid=$hostid]";
private static final String XML_GET_ALL = "/authent/entry";
private final File file;
public XMLHostDAO() {
file = new File(Configuration.configuration.getAuthFile());
}
@Override
public void close() {
// ignore
}
@Override
public void delete(final Host host) {
dbR66HostAuthHashMap.remove(host.getHostid());
}
@Override
public void deleteAll() {
dbR66HostAuthHashMap.clear();
}
@Override
public List<Host> getAll() throws DAOConnectionException {
if (!file.exists()) {
throw new DAOConnectionException("File doesn't exist");
}
try {
final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
final Document document = dbf.newDocumentBuilder().parse(file);
// Setup XPath query
final XPath xPath = XPathFactory.newInstance().newXPath();
final XPathExpression xpe = xPath.compile(XML_GET_ALL);
final NodeList listNode =
(NodeList) xpe.evaluate(document, XPathConstants.NODESET);
// Iterate through all found nodes
final List<Host> res = new ArrayList<Host>(listNode.getLength());
for (int i = 0; i < listNode.getLength(); i++) {
final Node node = listNode.item(i);
final Host host = getFromNode(node);
res.add(host);
dbR66HostAuthHashMap.put(host.getHostid(), host);
}
return res;
} catch (final SAXException e) {
throw new DAOConnectionException(e);
} catch (final XPathExpressionException e) {
throw new DAOConnectionException(e);
} catch (final ParserConfigurationException e) {
throw new DAOConnectionException(e);
} catch (final IOException e) {
throw new DAOConnectionException(e);
}
}
@Override
public boolean exist(final String hostid) throws DAOConnectionException {
if (dbR66HostAuthHashMap.containsKey(hostid)) {
return true;
}
if (!file.exists()) {
throw new DAOConnectionException("File doesn't exist");
}
try {
final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
final Document document = dbf.newDocumentBuilder().parse(file);
// Setup XPath variable
final SimpleVariableResolver resolver = new SimpleVariableResolver();
resolver.addVariable(new QName(null, HOSTID_FIELD), hostid);
// Setup XPath query
final XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setXPathVariableResolver(resolver);
final XPathExpression xpe = xPath.compile(XML_SELECT);
// Query will return "" if nothing is found
return ParametersChecker.isNotEmpty(xpe.evaluate(document));
} catch (final SAXException e) {
throw new DAOConnectionException(e);
} catch (final XPathExpressionException e) {
throw new DAOConnectionException(e);
} catch (final ParserConfigurationException e) {
throw new DAOConnectionException(e);
} catch (final IOException e) {
throw new DAOConnectionException(e);
}
}
@Override
public List<Host> find(final List<Filter> fitlers)
throws DAOConnectionException {
throw new DAOConnectionException("Operation not supported on XML DAO");
}
@Override
public List<Host> find(final List<Filter> filters, final int limit)
throws DAOConnectionException {
throw new DAOConnectionException("Operation not supported on XML DAO");
}
@Override
public List<Host> find(final List<Filter> filters, final String field,
final boolean asc) throws DAOConnectionException {
throw new DAOConnectionException("Operation not supported on XML DAO");
}
@Override
public List<Host> find(final List<Filter> filters, final String field,
final boolean asc, final int limit)
throws DAOConnectionException {
throw new DAOConnectionException("Operation not supported on XML DAO");
}
@Override
public List<Host> find(final List<Filter> filters, final String field,
final boolean asc, final int limit, final int offset)
throws DAOConnectionException {
throw new DAOConnectionException("Operation not supported on XML DAO");
}
@Override
public void update(final List<Filter> filters, final String toSet)
throws DAOConnectionException {
throw new DAOConnectionException("Operation not supported on XML DAO");
}
/**
* {@link DAOConnectionException}
*
* @return count only if filters is empty or null
*/
@Override
public long count(final List<Filter> fitlers) throws DAOConnectionException {
if (fitlers == null || fitlers.isEmpty()) {
return dbR66HostAuthHashMap.size();
}
throw new DAOConnectionException("Operation not supported on XML DAO");
}
@Override
public void insert(final Host host) {
dbR66HostAuthHashMap.put(host.getHostid(), host);
}
@Override
public Host select(final String hostid)
throws DAOConnectionException, DAONoDataException {
Host host = dbR66HostAuthHashMap.get(hostid);
if (host != null) {
return host;
}
if (!file.exists()) {
throw new DAOConnectionException(
"File " + file.getPath() + " doesn't exist");
}
try {
final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
final Document document = dbf.newDocumentBuilder().parse(file);
// Setup XPath variable
final SimpleVariableResolver resolver = new SimpleVariableResolver();
resolver.addVariable(new QName(null, HOSTID_FIELD), hostid);
// Setup XPath query
final XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setXPathVariableResolver(resolver);
final XPathExpression xpe = xPath.compile(XML_SELECT);
// Retrieve node and instantiate object
final Node node = (Node) xpe.evaluate(document, XPathConstants.NODE);
if (node != null) {
host = getFromNode(node);
dbR66HostAuthHashMap.put(host.getHostid(), host);
return host;
}
throw new DAONoDataException("Host not found");
} catch (final SAXException e) {
throw new DAOConnectionException(e);
} catch (final XPathExpressionException e) {
throw new DAOConnectionException(e);
} catch (final ParserConfigurationException e) {
throw new DAOConnectionException(e);
} catch (final IOException e) {
throw new DAOConnectionException(e);
}
}
@Override
public void update(final Host host) {
dbR66HostAuthHashMap.put(host.getHostid(), host);
}
private Host getFromNode(final Node parent) {
final Host res = new Host();
final NodeList children = parent.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
final Node node = children.item(j);
if (node.getNodeName().equals(HOSTID_FIELD)) {
res.setHostid(node.getTextContent());
} else if (node.getNodeName().equals(ADDRESS_FIELD)) {
res.setAddress(node.getTextContent());
} else if (node.getNodeName().equals(PORT_FIELD)) {
res.setPort(Integer.parseInt(node.getTextContent()));
} else if (node.getNodeName().equals(IS_SSL_FIELD)) {
res.setSSL(Boolean.parseBoolean(node.getTextContent()));
} else if (node.getNodeName().equals(IS_CLIENT_FIELD)) {
res.setClient(Boolean.parseBoolean(node.getTextContent()));
} else if (node.getNodeName().equals(IS_PROXIFIED_FIELD)) {
res.setProxified(Boolean.parseBoolean(node.getTextContent()));
} else if (node.getNodeName().equals(ADMINROLE_FIELD)) {
res.setAdmin(Boolean.parseBoolean(node.getTextContent()));
} else if (node.getNodeName().equals(HOSTKEY_FIELD)) {
res.setHostkey(node.getTextContent().getBytes(WaarpStringUtils.UTF8));
}
}
return res;
}
}