blob: 7f7370a101245825037635a753b50cc09606a5c2 [file] [log] [blame]
margaretha56e8e552017-12-05 16:31:21 +01001package de.ids_mannheim.korap.rewrite;
margarethadc731922017-05-22 17:20:42 +02002
margarethaa89c3f92017-05-30 19:02:08 +02003
margaretha416e7872017-06-20 15:05:17 +02004import java.util.ArrayList;
5import java.util.List;
margaretha416e7872017-06-20 15:05:17 +02006
margarethadc731922017-05-22 17:20:42 +02007import org.slf4j.Logger;
8import org.slf4j.LoggerFactory;
9
10import com.fasterxml.jackson.databind.JsonNode;
margaretha416e7872017-06-20 15:05:17 +020011import com.google.common.collect.Lists;
margarethadc731922017-05-22 17:20:42 +020012
13import de.ids_mannheim.korap.config.Attributes;
14import de.ids_mannheim.korap.config.KustvaktConfiguration;
margaretha56e8e552017-12-05 16:31:21 +010015import de.ids_mannheim.korap.config.FullConfiguration;
margarethadc731922017-05-22 17:20:42 +020016import de.ids_mannheim.korap.exceptions.KustvaktException;
margaretha416e7872017-06-20 15:05:17 +020017import de.ids_mannheim.korap.query.object.KoralMatchOperator;
margarethaed7bc7a2017-11-12 21:39:41 +010018import de.ids_mannheim.korap.query.object.KoralOperation;
margaretha56e8e552017-12-05 16:31:21 +010019import de.ids_mannheim.korap.resource.rewrite.KoralNode;
margarethadc731922017-05-22 17:20:42 +020020import de.ids_mannheim.korap.resource.rewrite.KoralNode.RewriteIdentifier;
margaretha56e8e552017-12-05 16:31:21 +010021import de.ids_mannheim.korap.resource.rewrite.RewriteTask;
margarethadc731922017-05-22 17:20:42 +020022import de.ids_mannheim.korap.user.User;
margarethabb486302017-11-21 13:47:22 +010023import de.ids_mannheim.korap.user.User.CorpusAccess;
margarethadc731922017-05-22 17:20:42 +020024import de.ids_mannheim.korap.utils.JsonUtils;
25import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
margarethabb486302017-11-21 13:47:22 +010026import edu.emory.mathcs.backport.java.util.Arrays;
margarethadc731922017-05-22 17:20:42 +020027
margarethabb486302017-11-21 13:47:22 +010028/** CollectionRewrite determines which availability field values are
29 * possible for a user with respect to his mean and location of access.
30 *
31 * <br/><br/>
32 * KorAP differentiates 3 kinds of access:
33 * <ul>
34 * <li>FREE: without login</li>
35 * <li>PUB: login outside IDS network</li>
36 * <li>ALL: login within IDS network</li>
37 * </ul>
38 *
39 * Each of these accesses corresponds to a regular expression of license
40 * formats defined in kustvakt.conf. For a given access, only those
41 * resources whose availability field matches its regular expression
42 * are allowed to be retrieved.
43 *
44 *
margarethadc731922017-05-22 17:20:42 +020045 * @author margaretha
margarethabb486302017-11-21 13:47:22 +010046 * @last-update 21 Nov 2017
47 * @see CorpusAccess
margarethadc731922017-05-22 17:20:42 +020048 */
49public class CollectionRewrite implements RewriteTask.RewriteQuery {
50
margarethabb486302017-11-21 13:47:22 +010051 private static Logger jlog =
52 LoggerFactory.getLogger(CollectionRewrite.class);
margarethadc731922017-05-22 17:20:42 +020053
margarethaa89c3f92017-05-30 19:02:08 +020054 public CollectionRewrite () {
55 super();
56 }
margarethadc731922017-05-22 17:20:42 +020057
margaretha416e7872017-06-20 15:05:17 +020058
margarethabb486302017-11-21 13:47:22 +010059 private List<String> checkAvailability (JsonNode node,
60 List<String> originalAvailabilities,
61 List<String> updatedAvailabilities, boolean isOperationOr) {
62 try {
63 jlog.debug(JsonUtils.toJSON(node));
64 }
65 catch (KustvaktException e) {
66 e.printStackTrace();
67 }
68
69 if (node.has("operands")) {
70 ArrayList<JsonNode> operands =
71 Lists.newArrayList(node.at("/operands").elements());
72
73 if (node.at("/operation").asText()
74 .equals(KoralOperation.AND.toString())) {
75 for (int i = 0; i < operands.size(); i++) {
76 updatedAvailabilities = checkAvailability(operands.get(i),
77 originalAvailabilities, updatedAvailabilities,
78 false);
79 if (updatedAvailabilities.isEmpty()) break;
80 }
81 }
82 else {
83 for (int i = 0; i < operands.size(); i++) {
84 updatedAvailabilities = checkAvailability(operands.get(i),
85 originalAvailabilities, updatedAvailabilities,
86 true);
87 }
margaretha416e7872017-06-20 15:05:17 +020088 }
89 }
90 else if (node.has("key")
91 && node.at("/key").asText().equals("availability")) {
92 String queryAvailability = node.at("/value").asText();
93 String matchOp = node.at("/match").asText();
margarethabb486302017-11-21 13:47:22 +010094 if (originalAvailabilities.contains(queryAvailability)
95 && matchOp.equals(KoralMatchOperator.EQUALS.toString())) {
96 jlog.debug("REMOVE " + queryAvailability);
97 updatedAvailabilities.remove(queryAvailability);
98 }
99 else if (isOperationOr) {
100 jlog.debug("RESET availabilities");
101 updatedAvailabilities.clear();
102 updatedAvailabilities.addAll(originalAvailabilities);
103 return updatedAvailabilities;
margaretha416e7872017-06-20 15:05:17 +0200104 }
105 }
margarethabb486302017-11-21 13:47:22 +0100106 return updatedAvailabilities;
margaretha416e7872017-06-20 15:05:17 +0200107 }
margarethadc731922017-05-22 17:20:42 +0200108
margarethaa89c3f92017-05-30 19:02:08 +0200109 @Override
110 public JsonNode rewriteQuery (KoralNode node, KustvaktConfiguration config,
111 User user) throws KustvaktException {
112 JsonNode jsonNode = node.rawNode();
margaretha56e8e552017-12-05 16:31:21 +0100113
114 FullConfiguration fullConfig = (FullConfiguration) config;
margarethabb486302017-11-21 13:47:22 +0100115
margaretha416e7872017-06-20 15:05:17 +0200116 List<String> userAvailabilities = new ArrayList<String>();
margarethaa89c3f92017-05-30 19:02:08 +0200117 switch (user.getCorpusAccess()) {
118 case PUB:
margarethadfecb4b2017-12-12 19:32:30 +0100119 userAvailabilities.addAll(fullConfig.getFreeRegexList());
120 userAvailabilities.addAll(fullConfig.getPublicRegexList());
margarethaa89c3f92017-05-30 19:02:08 +0200121 break;
122 case ALL:
margarethadfecb4b2017-12-12 19:32:30 +0100123 userAvailabilities.addAll(fullConfig.getFreeRegexList());
124 userAvailabilities.addAll(fullConfig.getPublicRegexList());
125 userAvailabilities.addAll(fullConfig.getAllRegexList());
margarethaa89c3f92017-05-30 19:02:08 +0200126 break;
127 case FREE:
margarethadfecb4b2017-12-12 19:32:30 +0100128 userAvailabilities.addAll(fullConfig.getFreeRegexList());
margarethaa89c3f92017-05-30 19:02:08 +0200129 break;
130 }
131
margaretha416e7872017-06-20 15:05:17 +0200132 KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
margarethaa89c3f92017-05-30 19:02:08 +0200133 RewriteIdentifier identifier = new KoralNode.RewriteIdentifier(
134 Attributes.AVAILABILITY, user.getCorpusAccess());
135 JsonNode rewrittesNode;
136
137 if (jsonNode.has("collection")) {
margarethabb486302017-11-21 13:47:22 +0100138 List<String> avalabilityCopy =
139 new ArrayList<String>(userAvailabilities.size());
140 avalabilityCopy.addAll(userAvailabilities);
141 jlog.debug("Availabilities: "
142 + Arrays.toString(userAvailabilities.toArray()));
143
144 userAvailabilities = checkAvailability(jsonNode.at("/collection"),
145 avalabilityCopy, userAvailabilities, false);
146 if (!userAvailabilities.isEmpty()) {
147 builder.with(buildAvailability(avalabilityCopy));
margarethacfea1ae2018-01-15 20:27:26 +0100148 jlog.debug("corpus query: " +builder.toString());
margaretha80b30ce2017-06-27 16:28:40 +0200149 builder.setBaseQuery(builder.toJSON());
150 rewrittesNode = builder.mergeWith(jsonNode).at("/collection");
151 node.set("collection", rewrittesNode, identifier);
margaretha3d7d3552017-06-26 17:45:36 +0200152 }
margarethaa89c3f92017-05-30 19:02:08 +0200153 }
154 else {
margaretha416e7872017-06-20 15:05:17 +0200155 builder.with(buildAvailability(userAvailabilities));
margarethacfea1ae2018-01-15 20:27:26 +0100156 jlog.debug("corpus query: " +builder.toString());
margarethabb486302017-11-21 13:47:22 +0100157 rewrittesNode =
158 JsonUtils.readTree(builder.toJSON()).at("/collection");
margarethaa89c3f92017-05-30 19:02:08 +0200159 node.set("collection", rewrittesNode, identifier);
160 }
161
margarethacfea1ae2018-01-15 20:27:26 +0100162 jlog.debug("REWRITES: " + node.at("/collection").toString());
margarethaa89c3f92017-05-30 19:02:08 +0200163 return node.rawNode();
164 }
margarethabb486302017-11-21 13:47:22 +0100165
166
margaretha416e7872017-06-20 15:05:17 +0200167 private String buildAvailability (List<String> userAvailabilities) {
168 StringBuilder sb = new StringBuilder();
margarethaad618d22017-12-11 19:58:49 +0100169 for (int i = 0; i < userAvailabilities.size(); i++) {
170 parseAvailability(sb, userAvailabilities.get(i), "|");
margaretha416e7872017-06-20 15:05:17 +0200171 }
margarethaad618d22017-12-11 19:58:49 +0100172 String availabilities = sb.toString();
173 return availabilities.substring(0, availabilities.length()-3);
margaretha416e7872017-06-20 15:05:17 +0200174 }
margarethaad618d22017-12-11 19:58:49 +0100175
176 private void parseAvailability (StringBuilder sb, String availability, String operator) {
177 String uaArr[] = null;
178 if (availability.contains("|")){
179 uaArr = availability.split("\\|");
180 for (int j=0; j < uaArr.length; j++){
181 parseAvailability(sb, uaArr[j].trim(), "|");
182 }
183 }
184 // EM: not supported
185// else if (availability.contains("&")){
186// uaArr = availability.split("&");
187// for (int j=0; j < uaArr.length -1; j++){
188// parseAvailability(sb, uaArr[j], "&");
189// }
190// parseAvailability(sb, uaArr[uaArr.length-1], "|");
191// }
192 else{
193 sb.append("availability=/");
194 sb.append(availability);
195 sb.append("/ ");
196 sb.append(operator);
197 sb.append(" ");
198 }
199
200 }
201
margarethadc731922017-05-22 17:20:42 +0200202}
margaretha416e7872017-06-20 15:05:17 +0200203