View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.access.mcrimpl;
20  
21  import java.text.ParseException;
22  import java.text.SimpleDateFormat;
23  import java.util.Date;
24  import java.util.Locale;
25  
26  import org.jdom2.Element;
27  import org.mycore.common.config.MCRConfiguration2;
28  import org.mycore.parsers.bool.MCRBooleanClauseParser;
29  import org.mycore.parsers.bool.MCRCondition;
30  import org.mycore.parsers.bool.MCRFalseCondition;
31  import org.mycore.parsers.bool.MCRIPCondition;
32  import org.mycore.parsers.bool.MCRParseException;
33  import org.mycore.parsers.bool.MCRTrueCondition;
34  
35  public class MCRRuleParser extends MCRBooleanClauseParser {
36      protected MCRRuleParser() {
37      }
38  
39      private static Date parseDate(String s, boolean dayafter) throws MCRParseException {
40          long time;
41          try {
42              time = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT).parse(s).getTime();
43          } catch (java.text.ParseException e) {
44              try {
45                  time = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT).parse(s).getTime();
46              } catch (ParseException e1) {
47                  throw new MCRParseException("unable to parse date " + s);
48              }
49          }
50  
51          if (dayafter) {
52              time += 1000 * 60 * 60 * 24;
53          }
54  
55          return new Date(time);
56      }
57  
58      @Override
59      protected MCRCondition<?> parseSimpleCondition(Element e) throws MCRParseException {
60          String name = e.getName();
61          switch (name) {
62          case "boolean":
63              return super.parseSimpleCondition(e);
64          case "condition":
65              MCRCondition<?> condition = parseElement(e);
66              if (condition == null) {
67                  throw new MCRParseException("Not a valid condition field <" + e.getAttributeValue("field") + ">");
68              }
69              return condition;
70          default:
71              throw new MCRParseException("Not a valid name <" + e.getName() + ">");
72          }
73      }
74  
75      @Override
76      protected MCRCondition<?> parseSimpleCondition(String s) throws MCRParseException {
77          MCRCondition<?> condition = parseString(s);
78          if (condition == null) {
79              throw new MCRParseException("syntax error: " + s);
80          }
81          return condition;
82      }
83  
84      protected MCRCondition<?> parseElement(Element e) {
85          String field = e.getAttributeValue("field").toLowerCase(Locale.ROOT).trim();
86          String operator = e.getAttributeValue("operator").trim();
87          String value = e.getAttributeValue("value").trim();
88          boolean not = "!=".equals(operator);
89  
90          switch (field) {
91          case "group":
92              return new MCRGroupClause(value, not);
93          case "user":
94              return new MCRUserClause(value, not);
95          case "ip":
96              return getIPClause(value);
97          case "date":
98              switch (operator) {
99              case "<":
100                 return new MCRDateBeforeClause(parseDate(value, false));
101             case "<=":
102                 return new MCRDateBeforeClause(parseDate(value, true));
103             case ">":
104                 return new MCRDateAfterClause(parseDate(value, true));
105             case ">=":
106                 return new MCRDateAfterClause(parseDate(value, false));
107             default:
108                 throw new MCRParseException("Not a valid operator <" + operator + ">");
109             }
110         default:
111             return null;
112         }
113     }
114 
115     private MCRCondition<MCRAccessData> getIPClause(String value) {
116         MCRIPCondition ipCond = MCRConfiguration2.<MCRIPCondition>getInstanceOf("MCR.RuleParser.ip")
117             .orElseGet(MCRIPClause::new);
118         ipCond.set(value);
119         return ipCond;
120     }
121 
122     protected MCRCondition<?> parseString(String s) {
123         /* handle specific rules */
124         if (s.equalsIgnoreCase("false")) {
125             return new MCRFalseCondition();
126         }
127 
128         if (s.equalsIgnoreCase("true")) {
129             return new MCRTrueCondition();
130         }
131 
132         if (s.startsWith("group")) {
133             s = s.substring(5).trim();
134             if (s.startsWith("!=")) {
135                 return new MCRGroupClause(s.substring(2).trim(), true);
136             } else if (s.startsWith("=")) {
137                 return new MCRGroupClause(s.substring(1).trim(), false);
138             } else {
139                 throw new MCRParseException("syntax error: " + s);
140             }
141         }
142 
143         if (s.startsWith("user")) {
144             s = s.substring(4).trim();
145             if (s.startsWith("!=")) {
146                 return new MCRUserClause(s.substring(2).trim(), true);
147             } else if (s.startsWith("=")) {
148                 return new MCRUserClause(s.substring(1).trim(), false);
149             } else {
150                 throw new MCRParseException("syntax error: " + s);
151             }
152         }
153 
154         if (s.startsWith("ip ")) {
155             return getIPClause(s.substring(3).trim());
156         }
157 
158         if (s.startsWith("date ")) {
159             s = s.substring(5).trim();
160             if (s.startsWith(">=")) {
161                 return new MCRDateAfterClause(parseDate(s.substring(2).trim(), false));
162             } else if (s.startsWith("<=")) {
163                 return new MCRDateBeforeClause(parseDate(s.substring(2).trim(), true));
164             } else if (s.startsWith(">")) {
165                 return new MCRDateAfterClause(parseDate(s.substring(1).trim(), true));
166             } else if (s.startsWith("<")) {
167                 return new MCRDateBeforeClause(parseDate(s.substring(1).trim(), false));
168             } else {
169                 throw new MCRParseException("syntax error: " + s);
170             }
171         }
172         return null;
173     }
174 }