1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.openr66.dao.xml;
22
23 import org.w3c.dom.Document;
24 import org.w3c.dom.Element;
25 import org.w3c.dom.Node;
26 import org.w3c.dom.NodeList;
27 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
28 import org.waarp.common.logging.WaarpLogger;
29 import org.waarp.common.logging.WaarpLoggerFactory;
30 import org.waarp.common.xml.XmlUtil;
31 import org.waarp.openr66.configuration.ExtensionFilter;
32 import org.waarp.openr66.dao.Filter;
33 import org.waarp.openr66.dao.RuleDAO;
34 import org.waarp.openr66.dao.exception.DAOConnectionException;
35 import org.waarp.openr66.dao.exception.DAONoDataException;
36 import org.waarp.openr66.pojo.Rule;
37 import org.waarp.openr66.pojo.RuleTask;
38 import org.waarp.openr66.protocol.configuration.Configuration;
39 import org.xml.sax.SAXException;
40
41 import javax.xml.parsers.DocumentBuilderFactory;
42 import javax.xml.parsers.ParserConfigurationException;
43 import javax.xml.xpath.XPath;
44 import javax.xml.xpath.XPathConstants;
45 import javax.xml.xpath.XPathExpression;
46 import javax.xml.xpath.XPathExpressionException;
47 import javax.xml.xpath.XPathFactory;
48 import java.io.File;
49 import java.io.IOException;
50 import java.util.ArrayList;
51 import java.util.Arrays;
52 import java.util.List;
53 import java.util.concurrent.ConcurrentHashMap;
54
55 import static org.waarp.openr66.dao.DAOFactory.*;
56 import static org.waarp.openr66.dao.database.DBRuleDAO.*;
57
58 public class XMLRuleDAO implements RuleDAO {
59
60 private static final WaarpLogger logger =
61 WaarpLoggerFactory.getLogger(XMLRuleDAO.class);
62
63
64
65
66 private static final ConcurrentHashMap<String, Rule> dbR66RuleHashMap =
67 new ConcurrentHashMap<String, Rule>();
68
69 public static final String ROOT_LIST = "rules";
70
71 private static final String XML_GET_ALL = "//rule";
72 private static final File[] FILE_0_LENGTH = new File[0];
73
74 public XMLRuleDAO() {
75
76 }
77
78 @Override
79 public final void close() {
80
81 }
82
83 public static final String EXT_RULE = ".rule.xml";
84 public static final String EXT_RULES = ".rules.xml";
85
86 private File[] getRuleFiles() {
87 final File ruleDir = new File(
88 Configuration.configuration.getBaseDirectory() +
89 Configuration.configuration.getConfigPath());
90 final List<File> res = new ArrayList<File>();
91 if (ruleDir.isDirectory()) {
92 res.addAll(
93 Arrays.asList(ruleDir.listFiles(new ExtensionFilter(EXT_RULE))));
94 res.addAll(
95 Arrays.asList(ruleDir.listFiles(new ExtensionFilter(EXT_RULES))));
96 }
97 return res.toArray(FILE_0_LENGTH);
98 }
99
100 @Override
101 public final void delete(final Rule rule) {
102 dbR66RuleHashMap.remove(rule.getName());
103 }
104
105 @Override
106 public final void deleteAll() {
107 dbR66RuleHashMap.clear();
108 }
109
110 @Override
111 public final List<Rule> getAll() throws DAOConnectionException {
112 final List<Rule> res = new ArrayList<Rule>();
113
114 final File[] files = getRuleFiles();
115 for (final File ruleFile : files) {
116 logger.debug("Load file {}", ruleFile.getAbsolutePath());
117 try {
118 final DocumentBuilderFactory dbf = getDocumentBuilderFactory();
119 final Document document = dbf.newDocumentBuilder().parse(ruleFile);
120
121 final XPath xPath = XPathFactory.newInstance().newXPath();
122 final XPathExpression xpe = xPath.compile(XML_GET_ALL);
123 final NodeList listNode =
124 (NodeList) xpe.evaluate(document, XPathConstants.NODESET);
125
126
127 for (int i = 0; i < listNode.getLength(); i++) {
128 final Node node = listNode.item(i);
129 final Rule rule = getFromNode(node);
130 res.add(rule);
131 dbR66RuleHashMap.put(rule.getName(), rule);
132 }
133 } catch (final SAXException e) {
134 throw new DAOConnectionException(e);
135 } catch (final XPathExpressionException e) {
136 throw new DAOConnectionException(e);
137 } catch (final ParserConfigurationException e) {
138 throw new DAOConnectionException(e);
139 } catch (final IOException e) {
140 throw new DAOConnectionException(e);
141 } catch (final Exception e) {
142 throw new DAOConnectionException(e);
143 }
144 }
145 return res;
146 }
147
148
149
150
151
152
153 @Override
154 public final long count(final List<Filter> fitlers)
155 throws DAOConnectionException {
156 if (fitlers == null || fitlers.isEmpty()) {
157 return dbR66RuleHashMap.size();
158 }
159 throw new DAOConnectionException("Operation not supported on XML DAO");
160 }
161
162 @Override
163 public final boolean exist(final String rulename) {
164 return dbR66RuleHashMap.containsKey(rulename);
165 }
166
167 @Override
168 public final List<Rule> find(final List<Filter> fitlers)
169 throws DAOConnectionException {
170 throw new DAOConnectionException("Operation not supported on XML DAO");
171 }
172
173 @Override
174 public List<Rule> find(final List<Filter> filters, final int limit)
175 throws DAOConnectionException {
176 throw new DAOConnectionException("Operation not supported on XML DAO");
177 }
178
179 @Override
180 public List<Rule> find(final List<Filter> filters, final String field,
181 final boolean asc) throws DAOConnectionException {
182 throw new DAOConnectionException("Operation not supported on XML DAO");
183 }
184
185 @Override
186 public List<Rule> find(final List<Filter> filters, final String field,
187 final boolean asc, final int limit)
188 throws DAOConnectionException {
189 throw new DAOConnectionException("Operation not supported on XML DAO");
190 }
191
192 @Override
193 public List<Rule> find(final List<Filter> filters, final String field,
194 final boolean asc, final int limit, final int offset)
195 throws DAOConnectionException {
196 throw new DAOConnectionException("Operation not supported on XML DAO");
197 }
198
199 @Override
200 public void update(final List<Filter> filters, final String toSet)
201 throws DAOConnectionException {
202 throw new DAOConnectionException("Operation not supported on XML DAO");
203 }
204
205 @Override
206 public final void insert(final Rule rule) {
207 dbR66RuleHashMap.put(rule.getName(), rule);
208 }
209
210 @Override
211 public final Rule select(final String rulename)
212 throws DAOConnectionException, DAONoDataException {
213 if (exist(rulename)) {
214 return dbR66RuleHashMap.get(rulename);
215 }
216 throw new DAONoDataException("Rule cannot be found");
217 }
218
219 @Override
220 public final void update(final Rule rule) {
221 dbR66RuleHashMap.put(rule.getName(), rule);
222 }
223
224 private Rule getFromNode(final Node parent) throws DAOConnectionException {
225 final Rule res = new Rule();
226
227 final NodeList children = parent.getChildNodes();
228 for (int j = 0; j < children.getLength(); j++) {
229 final Node node = children.item(j);
230 final String content = XmlUtil.getExtraTrimed(node.getTextContent());
231 if (node.getNodeName().equals(ID_FIELD)) {
232 res.setName(content);
233 } else if (node.getNodeName().equals(HOSTIDS_FIELD)) {
234 res.setHostids(retrieveHostids(node));
235 } else if (node.getNodeName().equals(MODE_TRANS_FIELD)) {
236 res.setMode(Integer.parseInt(content));
237 } else if (node.getNodeName().equals(SEND_PATH_FIELD)) {
238 try {
239 res.setSendPath(content);
240 } catch (final WaarpDatabaseSqlException e) {
241 throw new DAOConnectionException(e);
242 }
243 } else if (node.getNodeName().equals(RECV_PATH_FIELD)) {
244 try {
245 res.setRecvPath(content);
246 } catch (final WaarpDatabaseSqlException e) {
247 throw new DAOConnectionException(e);
248 }
249 } else if (node.getNodeName().equals(ARCHIVE_PATH_FIELD)) {
250 try {
251 res.setArchivePath(content);
252 } catch (final WaarpDatabaseSqlException e) {
253 throw new DAOConnectionException(e);
254 }
255 } else if (node.getNodeName().equals(WORK_PATH_FIELD)) {
256 try {
257 res.setWorkPath(content);
258 } catch (final WaarpDatabaseSqlException e) {
259 throw new DAOConnectionException(e);
260 }
261 } else if (node.getNodeName().equals(R_PRE_TASKS_FIELD)) {
262 res.setRPreTasks(retrieveTasks(node));
263 } else if (node.getNodeName().equals(R_POST_TASKS_FIELD)) {
264 res.setRPostTasks(retrieveTasks(node));
265 } else if (node.getNodeName().equals(R_ERROR_TASKS_FIELD)) {
266 res.setRErrorTasks(retrieveTasks(node));
267 } else if (node.getNodeName().equals(S_PRE_TASKS_FIELD)) {
268 res.setSPreTasks(retrieveTasks(node));
269 } else if (node.getNodeName().equals(S_POST_TASKS_FIELD)) {
270 res.setSPostTasks(retrieveTasks(node));
271 } else if (node.getNodeName().equals(S_ERROR_TASKS_FIELD)) {
272 res.setSErrorTasks(retrieveTasks(node));
273 }
274 }
275 return res;
276 }
277
278 private List<String> retrieveHostids(final Node xml)
279 throws DAOConnectionException {
280 final ArrayList<String> res = new ArrayList<String>();
281 if (xml == null || !xml.hasChildNodes()) {
282 return res;
283 }
284 final NodeList hostsList = xml.getChildNodes();
285 for (int i = 0; i < hostsList.getLength(); i++) {
286 res.add(XmlUtil.getExtraTrimed(hostsList.item(i).getTextContent()));
287 }
288 return res;
289 }
290
291 private List<RuleTask> retrieveTasks(final Node src) {
292 final List<RuleTask> res = new ArrayList<RuleTask>();
293 final NodeList feed = src.getChildNodes();
294 for (int i = 0; i < feed.getLength(); i++) {
295 final Node mainnode = feed.item(i);
296 if (mainnode.getNodeType() == Node.ELEMENT_NODE) {
297 final Element e = (Element) mainnode;
298 final NodeList tasksList = e.getElementsByTagName(TASK_NODE);
299 for (int j = 0; j < tasksList.getLength(); j++) {
300 final Node taskNode = tasksList.item(j);
301 if (taskNode.getNodeType() == Node.ELEMENT_NODE) {
302 final Element task = (Element) taskNode;
303 NodeList nodeList = task.getElementsByTagName(TYPE_FIELD);
304 if (nodeList == null || nodeList.getLength() == 0) {
305 logger.error("Field not found in Rule: " + TYPE_FIELD);
306 continue;
307 }
308 final String type =
309 XmlUtil.getExtraTrimed(nodeList.item(0).getTextContent());
310 nodeList = task.getElementsByTagName(PATH_FIELD);
311 final String path;
312 if (nodeList != null && nodeList.getLength() > 0) {
313 path = XmlUtil.getExtraTrimed(nodeList.item(0).getTextContent());
314 } else {
315 path = "";
316 }
317 nodeList = task.getElementsByTagName(DELAY_FIELD);
318 final int delay;
319 if (nodeList != null && nodeList.getLength() > 0) {
320 int tmpDelay = 0;
321 try {
322 tmpDelay = Integer.parseInt(
323 XmlUtil.getExtraTrimed(nodeList.item(0).getTextContent()));
324 } catch (final NumberFormatException ignored) {
325
326 }
327 delay = tmpDelay;
328 } else {
329 delay = 0;
330 }
331 final RuleTask ruleTask = new RuleTask(type, path, delay);
332 logger.debug("Task {}", ruleTask);
333 res.add(ruleTask);
334 }
335 }
336 }
337 }
338 return res;
339 }
340 }