View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  
21  package org.waarp.openr66.dao.xml;
22  
23  import org.w3c.dom.Document;
24  import org.w3c.dom.Node;
25  import org.w3c.dom.NodeList;
26  import org.waarp.common.utility.ParametersChecker;
27  import org.waarp.common.utility.WaarpStringUtils;
28  import org.waarp.openr66.dao.Filter;
29  import org.waarp.openr66.dao.HostDAO;
30  import org.waarp.openr66.dao.exception.DAOConnectionException;
31  import org.waarp.openr66.dao.exception.DAONoDataException;
32  import org.waarp.openr66.pojo.Host;
33  import org.waarp.openr66.protocol.configuration.Configuration;
34  import org.xml.sax.SAXException;
35  
36  import javax.xml.namespace.QName;
37  import javax.xml.parsers.DocumentBuilderFactory;
38  import javax.xml.parsers.ParserConfigurationException;
39  import javax.xml.xpath.XPath;
40  import javax.xml.xpath.XPathConstants;
41  import javax.xml.xpath.XPathExpression;
42  import javax.xml.xpath.XPathExpressionException;
43  import javax.xml.xpath.XPathFactory;
44  import java.io.File;
45  import java.io.IOException;
46  import java.util.ArrayList;
47  import java.util.List;
48  import java.util.concurrent.ConcurrentHashMap;
49  
50  import static org.waarp.openr66.dao.DAOFactory.*;
51  import static org.waarp.openr66.dao.database.DBHostDAO.*;
52  
53  public class XMLHostDAO implements HostDAO {
54  
55    /**
56     * HashTable in case of lack of database
57     */
58    private static final ConcurrentHashMap<String, Host> dbR66HostAuthHashMap =
59        new ConcurrentHashMap<String, Host>();
60  
61    private static final String XML_SELECT = "/authent/entry[hostid=$hostid]";
62    private static final String XML_GET_ALL = "/authent/entry";
63  
64    private final File file;
65  
66    public XMLHostDAO() {
67      file = new File(Configuration.configuration.getAuthFile());
68    }
69  
70    @Override
71    public void close() {
72      // ignore
73    }
74  
75    @Override
76    public void delete(final Host host) {
77      dbR66HostAuthHashMap.remove(host.getHostid());
78    }
79  
80    @Override
81    public void deleteAll() {
82      dbR66HostAuthHashMap.clear();
83    }
84  
85    @Override
86    public List<Host> getAll() throws DAOConnectionException {
87      if (!file.exists()) {
88        throw new DAOConnectionException("File doesn't exist");
89      }
90      try {
91        final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
92        final Document document = dbf.newDocumentBuilder().parse(file);
93        // Setup XPath query
94        final XPath xPath = XPathFactory.newInstance().newXPath();
95        final XPathExpression xpe = xPath.compile(XML_GET_ALL);
96        final NodeList listNode =
97            (NodeList) xpe.evaluate(document, XPathConstants.NODESET);
98        // Iterate through all found nodes
99        final List<Host> res = new ArrayList<Host>(listNode.getLength());
100       for (int i = 0; i < listNode.getLength(); i++) {
101         final Node node = listNode.item(i);
102         final Host host = getFromNode(node);
103         res.add(host);
104         dbR66HostAuthHashMap.put(host.getHostid(), host);
105       }
106       return res;
107     } catch (final SAXException e) {
108       throw new DAOConnectionException(e);
109     } catch (final XPathExpressionException e) {
110       throw new DAOConnectionException(e);
111     } catch (final ParserConfigurationException e) {
112       throw new DAOConnectionException(e);
113     } catch (final IOException e) {
114       throw new DAOConnectionException(e);
115     }
116   }
117 
118   @Override
119   public boolean exist(final String hostid) throws DAOConnectionException {
120     if (dbR66HostAuthHashMap.containsKey(hostid)) {
121       return true;
122     }
123     if (!file.exists()) {
124       throw new DAOConnectionException("File doesn't exist");
125     }
126     try {
127       final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
128       final Document document = dbf.newDocumentBuilder().parse(file);
129       // Setup XPath variable
130       final SimpleVariableResolver resolver = new SimpleVariableResolver();
131       resolver.addVariable(new QName(null, HOSTID_FIELD), hostid);
132       // Setup XPath query
133       final XPath xPath = XPathFactory.newInstance().newXPath();
134       xPath.setXPathVariableResolver(resolver);
135       final XPathExpression xpe = xPath.compile(XML_SELECT);
136       // Query will return "" if nothing is found
137       return ParametersChecker.isNotEmpty(xpe.evaluate(document));
138     } catch (final SAXException e) {
139       throw new DAOConnectionException(e);
140     } catch (final XPathExpressionException e) {
141       throw new DAOConnectionException(e);
142     } catch (final ParserConfigurationException e) {
143       throw new DAOConnectionException(e);
144     } catch (final IOException e) {
145       throw new DAOConnectionException(e);
146     }
147   }
148 
149   @Override
150   public List<Host> find(final List<Filter> fitlers)
151       throws DAOConnectionException {
152     throw new DAOConnectionException("Operation not supported on XML DAO");
153   }
154 
155   @Override
156   public List<Host> find(final List<Filter> filters, final int limit)
157       throws DAOConnectionException {
158     throw new DAOConnectionException("Operation not supported on XML DAO");
159   }
160 
161   @Override
162   public List<Host> find(final List<Filter> filters, final String field,
163                          final boolean asc) throws DAOConnectionException {
164     throw new DAOConnectionException("Operation not supported on XML DAO");
165   }
166 
167   @Override
168   public List<Host> find(final List<Filter> filters, final String field,
169                          final boolean asc, final int limit)
170       throws DAOConnectionException {
171     throw new DAOConnectionException("Operation not supported on XML DAO");
172   }
173 
174   @Override
175   public List<Host> find(final List<Filter> filters, final String field,
176                          final boolean asc, final int limit, final int offset)
177       throws DAOConnectionException {
178     throw new DAOConnectionException("Operation not supported on XML DAO");
179   }
180 
181   @Override
182   public void update(final List<Filter> filters, final String toSet)
183       throws DAOConnectionException {
184     throw new DAOConnectionException("Operation not supported on XML DAO");
185   }
186 
187   /**
188    * {@link DAOConnectionException}
189    *
190    * @return count only if filters is empty or null
191    */
192   @Override
193   public long count(final List<Filter> fitlers) throws DAOConnectionException {
194     if (fitlers == null || fitlers.isEmpty()) {
195       return dbR66HostAuthHashMap.size();
196     }
197     throw new DAOConnectionException("Operation not supported on XML DAO");
198   }
199 
200   @Override
201   public void insert(final Host host) {
202     dbR66HostAuthHashMap.put(host.getHostid(), host);
203   }
204 
205   @Override
206   public Host select(final String hostid)
207       throws DAOConnectionException, DAONoDataException {
208     Host host = dbR66HostAuthHashMap.get(hostid);
209     if (host != null) {
210       return host;
211     }
212     if (!file.exists()) {
213       throw new DAOConnectionException(
214           "File " + file.getPath() + " doesn't exist");
215     }
216     try {
217       final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
218       final Document document = dbf.newDocumentBuilder().parse(file);
219       // Setup XPath variable
220       final SimpleVariableResolver resolver = new SimpleVariableResolver();
221       resolver.addVariable(new QName(null, HOSTID_FIELD), hostid);
222       // Setup XPath query
223       final XPath xPath = XPathFactory.newInstance().newXPath();
224       xPath.setXPathVariableResolver(resolver);
225       final XPathExpression xpe = xPath.compile(XML_SELECT);
226       // Retrieve node and instantiate object
227       final Node node = (Node) xpe.evaluate(document, XPathConstants.NODE);
228       if (node != null) {
229         host = getFromNode(node);
230         dbR66HostAuthHashMap.put(host.getHostid(), host);
231         return host;
232       }
233       throw new DAONoDataException("Host not found");
234     } catch (final SAXException e) {
235       throw new DAOConnectionException(e);
236     } catch (final XPathExpressionException e) {
237       throw new DAOConnectionException(e);
238     } catch (final ParserConfigurationException e) {
239       throw new DAOConnectionException(e);
240     } catch (final IOException e) {
241       throw new DAOConnectionException(e);
242     }
243   }
244 
245   @Override
246   public void update(final Host host) {
247     dbR66HostAuthHashMap.put(host.getHostid(), host);
248   }
249 
250   private Host getFromNode(final Node parent) {
251     final Host res = new Host();
252 
253     final NodeList children = parent.getChildNodes();
254     for (int j = 0; j < children.getLength(); j++) {
255       final Node node = children.item(j);
256       if (node.getNodeName().equals(HOSTID_FIELD)) {
257         res.setHostid(node.getTextContent());
258       } else if (node.getNodeName().equals(ADDRESS_FIELD)) {
259         res.setAddress(node.getTextContent());
260       } else if (node.getNodeName().equals(PORT_FIELD)) {
261         res.setPort(Integer.parseInt(node.getTextContent()));
262       } else if (node.getNodeName().equals(IS_SSL_FIELD)) {
263         res.setSSL(Boolean.parseBoolean(node.getTextContent()));
264       } else if (node.getNodeName().equals(IS_CLIENT_FIELD)) {
265         res.setClient(Boolean.parseBoolean(node.getTextContent()));
266       } else if (node.getNodeName().equals(IS_PROXIFIED_FIELD)) {
267         res.setProxified(Boolean.parseBoolean(node.getTextContent()));
268       } else if (node.getNodeName().equals(ADMINROLE_FIELD)) {
269         res.setAdmin(Boolean.parseBoolean(node.getTextContent()));
270       } else if (node.getNodeName().equals(HOSTKEY_FIELD)) {
271         res.setHostkey(node.getTextContent().getBytes(WaarpStringUtils.UTF8));
272       }
273     }
274     return res;
275   }
276 }