Fixed rewrite redundancy in collection rewrite.
Change-Id: Id3c4744449064e21f02d682fe62bc07dc6201a6f
diff --git a/core/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java b/core/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
index 8937d42..60402ac 100644
--- a/core/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
+++ b/core/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
@@ -17,70 +17,110 @@
import de.ids_mannheim.korap.query.object.KoralOperation;
import de.ids_mannheim.korap.resource.rewrite.KoralNode.RewriteIdentifier;
import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.User.CorpusAccess;
import de.ids_mannheim.korap.utils.JsonUtils;
import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
+import edu.emory.mathcs.backport.java.util.Arrays;
-/**
+/** CollectionRewrite determines which availability field values are
+ * possible for a user with respect to his mean and location of access.
+ *
+ * <br/><br/>
+ * KorAP differentiates 3 kinds of access:
+ * <ul>
+ * <li>FREE: without login</li>
+ * <li>PUB: login outside IDS network</li>
+ * <li>ALL: login within IDS network</li>
+ * </ul>
+ *
+ * Each of these accesses corresponds to a regular expression of license
+ * formats defined in kustvakt.conf. For a given access, only those
+ * resources whose availability field matches its regular expression
+ * are allowed to be retrieved.
+ *
+ *
* @author margaretha
- * @date 2 June 2017
- * @last 9 Nov 2017
+ * @last-update 21 Nov 2017
+ * @see CorpusAccess
*/
public class CollectionRewrite implements RewriteTask.RewriteQuery {
- private static Logger jlog = LoggerFactory
- .getLogger(CollectionRewrite.class);
+ private static Logger jlog =
+ LoggerFactory.getLogger(CollectionRewrite.class);
public CollectionRewrite () {
super();
}
-
- private List<String> checkAvailability (JsonNode node, List<String> userAvailabilities) {
- if (node.has("operands") && node.at("/operation").asText().equals(KoralOperation.AND.toString())) {
- ArrayList<JsonNode> operands = Lists
- .newArrayList(node.at("/operands").elements());
- for (int i = 0; i < operands.size(); i++) {
- userAvailabilities = checkAvailability(operands.get(i), userAvailabilities);
+ private List<String> checkAvailability (JsonNode node,
+ List<String> originalAvailabilities,
+ List<String> updatedAvailabilities, boolean isOperationOr) {
+ try {
+ jlog.debug(JsonUtils.toJSON(node));
+ }
+ catch (KustvaktException e) {
+ e.printStackTrace();
+ }
+
+ if (node.has("operands")) {
+ ArrayList<JsonNode> operands =
+ Lists.newArrayList(node.at("/operands").elements());
+
+ if (node.at("/operation").asText()
+ .equals(KoralOperation.AND.toString())) {
+ for (int i = 0; i < operands.size(); i++) {
+ updatedAvailabilities = checkAvailability(operands.get(i),
+ originalAvailabilities, updatedAvailabilities,
+ false);
+ if (updatedAvailabilities.isEmpty()) break;
+ }
+ }
+ else {
+ for (int i = 0; i < operands.size(); i++) {
+ updatedAvailabilities = checkAvailability(operands.get(i),
+ originalAvailabilities, updatedAvailabilities,
+ true);
+ }
}
}
else if (node.has("key")
&& node.at("/key").asText().equals("availability")) {
String queryAvailability = node.at("/value").asText();
String matchOp = node.at("/match").asText();
- if (userAvailabilities.contains(queryAvailability) && matchOp.
- equals(KoralMatchOperator.EQUALS.toString())){
- userAvailabilities.remove(queryAvailability);
+ if (originalAvailabilities.contains(queryAvailability)
+ && matchOp.equals(KoralMatchOperator.EQUALS.toString())) {
+ jlog.debug("REMOVE " + queryAvailability);
+ updatedAvailabilities.remove(queryAvailability);
+ }
+ else if (isOperationOr) {
+ jlog.debug("RESET availabilities");
+ updatedAvailabilities.clear();
+ updatedAvailabilities.addAll(originalAvailabilities);
+ return updatedAvailabilities;
}
}
-
- return userAvailabilities;
+ return updatedAvailabilities;
}
@Override
public JsonNode rewriteQuery (KoralNode node, KustvaktConfiguration config,
User user) throws KustvaktException {
JsonNode jsonNode = node.rawNode();
-
+
List<String> userAvailabilities = new ArrayList<String>();
switch (user.getCorpusAccess()) {
case PUB:
userAvailabilities.add(config.getFreeOnlyRegex());
userAvailabilities.add(config.getPublicOnlyRegex());
-// builder.with(
-// "availability = /CC-BY.*/ | availability = /ACA.*/");
break;
case ALL:
userAvailabilities.add(config.getFreeOnlyRegex());
userAvailabilities.add(config.getPublicOnlyRegex());
userAvailabilities.add(config.getAllOnlyRegex());
-
-// builder.with("availability = /QAO.*/ | availability = /ACA.*/ |"
-// + " availability = /CC-BY.*/");
break;
case FREE:
userAvailabilities.add(config.getFreeOnlyRegex());
-// builder.with("availability = /CC-BY.*/");
break;
}
@@ -90,9 +130,16 @@
JsonNode rewrittesNode;
if (jsonNode.has("collection")) {
- userAvailabilities = checkAvailability(jsonNode.at("/collection"), userAvailabilities);
- if (!userAvailabilities.isEmpty()){
- builder.with(buildAvailability(userAvailabilities));
+ List<String> avalabilityCopy =
+ new ArrayList<String>(userAvailabilities.size());
+ avalabilityCopy.addAll(userAvailabilities);
+ jlog.debug("Availabilities: "
+ + Arrays.toString(userAvailabilities.toArray()));
+
+ userAvailabilities = checkAvailability(jsonNode.at("/collection"),
+ avalabilityCopy, userAvailabilities, false);
+ if (!userAvailabilities.isEmpty()) {
+ builder.with(buildAvailability(avalabilityCopy));
builder.setBaseQuery(builder.toJSON());
rewrittesNode = builder.mergeWith(jsonNode).at("/collection");
node.set("collection", rewrittesNode, identifier);
@@ -100,25 +147,25 @@
}
else {
builder.with(buildAvailability(userAvailabilities));
- rewrittesNode = JsonUtils.readTree(builder.toJSON())
- .at("/collection");
+ rewrittesNode =
+ JsonUtils.readTree(builder.toJSON()).at("/collection");
node.set("collection", rewrittesNode, identifier);
}
jlog.info("REWRITES: " + node.at("/collection").toString());
return node.rawNode();
}
-
-
+
+
private String buildAvailability (List<String> userAvailabilities) {
StringBuilder sb = new StringBuilder();
- for (int i=0; i < userAvailabilities.size()-1; i++){
+ for (int i = 0; i < userAvailabilities.size() - 1; i++) {
sb.append("availability=/");
sb.append(userAvailabilities.get(i));
sb.append("/ | ");
}
sb.append("availability=/");
- sb.append(userAvailabilities.get(userAvailabilities.size()-1));
+ sb.append(userAvailabilities.get(userAvailabilities.size() - 1));
sb.append("/");
return sb.toString();
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
index 7ee3506..60c3126 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
@@ -231,13 +231,11 @@
corpusAccess = CorpusAccess.PUB;
}
- if (DEBUG_LOG == true) {
- System.out.printf("Debug: X-Forwarded-For : '%s' (%d values) -> %s\n",
- Arrays.toString(vals), vals.length, vals[0]);
- System.out.printf("Debug: X-Forwarded-For : location = %s corpusAccess = %s\n",
- location == Location.INTERN ? "INTERN" : "EXTERN", corpusAccess == CorpusAccess.ALL ? "ALL"
- : corpusAccess == CorpusAccess.PUB ? "PUB" : "FREE");
- }
+ jlog.debug(String.format("X-Forwarded-For : '%s' (%d values) -> %s\n",
+ Arrays.toString(vals), vals.length, vals[0]));
+ jlog.debug(String.format("X-Forwarded-For : location = %s corpusAccess = %s\n",
+ location == Location.INTERN ? "INTERN" : "EXTERN", corpusAccess == CorpusAccess.ALL ? "ALL"
+ : corpusAccess == CorpusAccess.PUB ? "PUB" : "FREE"));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
diff --git a/full/src/main/resources/log4j.properties b/full/src/main/resources/log4j.properties
index 308c9ca..7f9c1ca 100644
--- a/full/src/main/resources/log4j.properties
+++ b/full/src/main/resources/log4j.properties
@@ -6,7 +6,7 @@
#log4j.logger.de.ids_mannheim.korap.service.VirtualCorpusService = error, debugLog
#log4j.logger.de.ids_mannheim.korap.web.controller.AuthenticationController = debug, debugLog, stdout
-
+log4j.logger.de.ids_mannheim.korap.resource.rewrite.CollectionRewrite= stdout, debugLog
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
@@ -36,4 +36,4 @@
log4j.logger.de.ids_mannheim.korap.security.ac = ERROR, policyLog
-log4j.logger.de.ids_mannheim.korap.security.auth = ERROR, authLog
\ No newline at end of file
+log4j.logger.de.ids_mannheim.korap.authentication = debug, authLog
\ No newline at end of file
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
index 7328064..cf19694 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
@@ -64,21 +64,17 @@
node.at("/collection/rewrites/0/scope").asText());
}
- private void checkAndPublicWithoutACA (String json)
+ private void checkAndPublicWithACA (String json)
throws KustvaktException {
JsonNode node = JsonUtils.readTree(json);
assertNotNull(node);
assertEquals("operation:and",
node.at("/collection/operation").asText());
- assertEquals("match:eq",
- node.at("/collection/operands/0/match").asText());
- assertEquals("type:regex",
- node.at("/collection/operands/0/type").asText());
- assertEquals("availability",
- node.at("/collection/operands/0/key").asText());
- assertEquals("CC-BY.*",
- node.at("/collection/operands/0/value").asText());
-
+ assertEquals("operation:insertion",
+ node.at("/collection/rewrites/0/operation").asText());
+ assertEquals("availability(PUB)",
+ node.at("/collection/rewrites/0/scope").asText());
+
assertEquals("match:eq",
node.at("/collection/operands/1/match").asText());
assertEquals("type:regex",
@@ -86,11 +82,26 @@
assertEquals("availability",
node.at("/collection/operands/1/key").asText());
assertEquals("ACA.*", node.at("/collection/operands/1/value").asText());
+
+ node = node.at("/collection/operands/0");
+ assertEquals("match:eq",
+ node.at("/operands/0/match").asText());
+ assertEquals("type:regex",
+ node.at("/operands/0/type").asText());
+ assertEquals("availability",
+ node.at("/operands/0/key").asText());
+ assertEquals("CC-BY.*",
+ node.at("/operands/0/value").asText());
- assertEquals("operation:insertion",
- node.at("/collection/rewrites/0/operation").asText());
- assertEquals("availability(PUB)",
- node.at("/collection/rewrites/0/scope").asText());
+ assertEquals("match:eq",
+ node.at("/operands/1/match").asText());
+ assertEquals("type:regex",
+ node.at("/operands/1/type").asText());
+ assertEquals("availability",
+ node.at("/operands/1/key").asText());
+ assertEquals("ACA.*", node.at("/operands/1/value").asText());
+
+
}
private void checkAndAll (String json) throws KustvaktException {
@@ -122,27 +133,39 @@
}
- private void checkAndAllWithoutACA (String json) throws KustvaktException {
+ private void checkAndAllWithACA (String json) throws KustvaktException {
JsonNode node = JsonUtils.readTree(json);
assertNotNull(node);
assertEquals("operation:and",
node.at("/collection/operation").asText());
- assertEquals("match:eq",
- node.at("/collection/operands/0/operands/0/match").asText());
- assertEquals("type:regex",
- node.at("/collection/operands/0/operands/0/type").asText());
- assertEquals("availability",
- node.at("/collection/operands/0/operands/0/key").asText());
- assertEquals("CC-BY.*",
- node.at("/collection/operands/0/operands/0/value").asText());
- assertEquals("match:eq",
- node.at("/collection/operands/0/operands/1/match").asText());
- assertEquals("QAO.*",
- node.at("/collection/operands/0/operands/1/value").asText());
assertEquals("operation:insertion",
node.at("/collection/rewrites/0/operation").asText());
assertEquals("availability(ALL)",
node.at("/collection/rewrites/0/scope").asText());
+
+ assertEquals("match:eq",
+ node.at("/collection/operands/1/match").asText());
+ assertEquals("type:regex",
+ node.at("/collection/operands/1/type").asText());
+ assertEquals("availability",
+ node.at("/collection/operands/1/key").asText());
+ assertEquals("ACA.*", node.at("/collection/operands/1/value").asText());
+
+ node = node.at("/collection/operands/0");
+
+ assertEquals("match:eq",
+ node.at("/operands/0/match").asText());
+ assertEquals("type:regex",
+ node.at("/operands/0/type").asText());
+ assertEquals("availability",
+ node.at("/operands/0/key").asText());
+ assertEquals("CC-BY.*",
+ node.at("/operands/0/value").asText());
+ assertEquals("match:eq",
+ node.at("/operands/1/operands/1/match").asText());
+ assertEquals("QAO.*",
+ node.at("/operands/1/operands/1/value").asText());
+
}
@@ -350,7 +373,7 @@
assertEquals(ClientResponse.Status.OK.getStatusCode(),
response.getStatus());
- checkAndPublicWithoutACA(response.getEntity(String.class));
+ checkAndPublicWithACA(response.getEntity(String.class));
}
@@ -412,7 +435,7 @@
assertEquals(ClientResponse.Status.OK.getStatusCode(),
response.getStatus());
- checkAndAllWithoutACA(response.getEntity(String.class));
+ checkAndAllWithACA(response.getEntity(String.class));
}
}