userdata retrieval via json pointer
Change-Id: I58baf039958570ebaeb07afad7279b9424c62ece
diff --git a/src/main/java/de/ids_mannheim/korap/user/DataFactory.java b/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
new file mode 100644
index 0000000..be6f02f
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
@@ -0,0 +1,222 @@
+package de.ids_mannheim.korap.user;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+import java.util.*;
+
+/**
+ * @author hanl
+ * @date 27/01/2016
+ */
+public abstract class DataFactory {
+
+ private static final Map<Class<? extends Userdata>, UserDataDbIface> instances = new HashMap<>();
+
+ private static DataFactory factory;
+
+
+ private DataFactory () {}
+
+
+ public static DataFactory getFactory () {
+ if (factory == null)
+ factory = new DefaultFactory();
+ return factory;
+ }
+
+
+ /**
+ * if data string null, returns an empty data holding object
+ *
+ * @param data
+ * @return
+ */
+ public abstract Object convertData (String data);
+
+
+ public abstract int size (Object data);
+
+
+ public abstract Set<String> keys (Object data);
+
+
+ public abstract Collection<Object> values (Object data);
+
+
+ @Deprecated
+ public abstract Map<String, Object> fields (Object data);
+
+
+ public abstract Object getValue (Object data, String pointer);
+
+
+ public abstract boolean addValue (Object data, String field, Object value);
+
+
+ public abstract boolean removeValue (Object data, String field);
+
+
+ public abstract String toStringValue (Object data);
+
+
+ public boolean checkDataType (Object data) {
+ throw new RuntimeException("Wrong data type for factory setting!");
+ }
+
+
+ /**
+ * updates data1 with values from data2
+ *
+ * @param data1
+ * data object that needs update
+ * @param data2
+ * values that update data1
+ * @return
+ */
+ public abstract Object merge (Object data1, Object data2);
+
+
+
+ private static class DefaultFactory extends DataFactory {
+
+ @Override
+ public Object convertData (String data) {
+ if (data == null)
+ return JsonUtils.createObjectNode();
+ return JsonUtils.readTree(data);
+ }
+
+
+ @Override
+ public int size (Object data) {
+ if (checkDataType(data))
+ return ((JsonNode) data).size();
+ return -1;
+ }
+
+
+ @Override
+ public Set<String> keys (Object data) {
+ Set<String> keys = new HashSet<>();
+ if (checkDataType(data) && ((JsonNode) data).isObject()) {
+ Iterator it = ((JsonNode) data).fieldNames();
+ while (it.hasNext())
+ keys.add((String) it.next());
+ }
+ return keys;
+ }
+
+
+ @Override
+ public Collection<Object> values (Object data) {
+ return new HashSet<>();
+ }
+
+
+ @Override
+ public Map<String, Object> fields (Object data) {
+ return new HashMap<>();
+ }
+
+
+ @Override
+ public Object getValue (Object data, String key) {
+ if (checkDataType(data)) {
+ JsonNode value;
+ if (key.startsWith("/"))
+ value = ((JsonNode) data).at(key);
+ else
+ value = ((JsonNode) data).path(key);
+
+ if (value.canConvertToInt())
+ return value.asInt();
+ else if (value.isBoolean())
+ return value.asBoolean();
+ else if (value.isTextual())
+ return value.asText();
+ }
+ return null;
+ }
+
+
+ //fixme: test that this works with different types
+ @Override
+ public boolean addValue (Object data, String field, Object value) {
+ if (checkDataType(data)) {
+ if (((JsonNode) data).isObject()) {
+ ObjectNode node = (ObjectNode) data;
+ if (value instanceof String)
+ node.put(field, (String) value);
+ if (value instanceof Boolean)
+ node.put(field, (Boolean) value);
+ if (value instanceof Integer)
+ node.put(field, (Integer) value);
+ if (value instanceof JsonNode)
+ node.put(field, (JsonNode) value);
+ return true;
+ }
+ else if (((JsonNode) data).isArray()) {
+ ArrayNode node = (ArrayNode) data;
+ if (value instanceof String)
+ node.add((String) value);
+ if (value instanceof Boolean)
+ node.add((Boolean) value);
+ if (value instanceof Integer)
+ node.add((Integer) value);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ @Override
+ public boolean removeValue (Object data, String field) {
+ if (checkDataType(data) && ((JsonNode) data).isObject()) {
+ ObjectNode node = (ObjectNode) data;
+ node.remove(field);
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public String toStringValue (Object data) {
+ if (data instanceof JsonNode)
+ return JsonUtils.toJSON(data);
+ return data.toString();
+ }
+
+
+ @Override
+ public boolean checkDataType (Object data) {
+ if (!(data instanceof JsonNode))
+ super.checkDataType(data);
+ return true;
+ }
+
+
+ @Override
+ public Object merge (Object data1, Object data2) {
+ if (checkDataType(data1) && checkDataType(data2)) {
+ if (((JsonNode) data1).isObject()
+ && ((JsonNode) data2).isObject()) {
+ ((ObjectNode) data1).putAll((ObjectNode) data2);
+ }
+ else if (((JsonNode) data1).isArray()
+ && ((JsonNode) data2).isArray()) {
+ ((ArrayNode) data1).addAll((ArrayNode) data2);
+ }
+ }
+ return data1;
+ }
+
+ }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/user/GenericUserData.java b/src/main/java/de/ids_mannheim/korap/user/GenericUserData.java
new file mode 100644
index 0000000..cf254dd
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/user/GenericUserData.java
@@ -0,0 +1,24 @@
+package de.ids_mannheim.korap.user;
+
+/**
+ * Created by hanl on 07.06.16.
+ */
+public class GenericUserData extends Userdata {
+
+
+ public GenericUserData () {
+ super(-1);
+ }
+
+
+ @Override
+ public String[] requiredFields () {
+ return new String[0];
+ }
+
+
+ @Override
+ public String[] defaultFields () {
+ return new String[0];
+ }
+}
diff --git a/src/test/java/de/ids_mannheim/korap/config/BeanInjectTest.java b/src/test/java/de/ids_mannheim/korap/config/BeanInjectTest.java
new file mode 100644
index 0000000..cd2f480
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/config/BeanInjectTest.java
@@ -0,0 +1,58 @@
+package de.ids_mannheim.korap.config;
+
+import de.ids_mannheim.korap.handlers.DocumentDao;
+import de.ids_mannheim.korap.handlers.ResourceDao;
+import de.ids_mannheim.korap.handlers.UserDetailsDao;
+import de.ids_mannheim.korap.handlers.UserSettingsDao;
+import de.ids_mannheim.korap.resources.Document;
+import de.ids_mannheim.korap.resources.KustvaktResource;
+import de.ids_mannheim.korap.user.UserDetails;
+import de.ids_mannheim.korap.user.UserSettings;
+import org.junit.Test;
+import org.springframework.aop.support.AopUtils;
+
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Created by hanl on 03.06.16.
+ */
+public class BeanInjectTest {
+
+
+
+ @Test
+ public void testUserBeans () {
+ BeansFactory.loadClasspathContext("default-config.xml");
+ Collection coll = BeansFactory.getKustvaktContext()
+ .getUserDataProviders();
+ assertFalse(coll.isEmpty());
+ Object o = BeansFactory.getTypeFactory().getTypeInterfaceBean(coll,
+ UserSettings.class);
+ assertEquals(UserSettingsDao.class, AopUtils.getTargetClass(o));
+
+ o = BeansFactory.getTypeFactory().getTypeInterfaceBean(coll,
+ UserDetails.class);
+ assertEquals(UserDetailsDao.class, AopUtils.getTargetClass(o));
+ BeansFactory.closeApplication();
+ }
+
+
+ @Test
+ public void testResourceBeans () {
+ BeansFactory.loadClasspathContext("default-config.xml");
+ Collection coll = BeansFactory.getKustvaktContext()
+ .getResourceProviders();
+ assertFalse(coll.isEmpty());
+ Object o = BeansFactory.getTypeFactory().getTypeInterfaceBean(coll,
+ Document.class);
+ assertEquals(DocumentDao.class, AopUtils.getTargetClass(o));
+
+ o = BeansFactory.getTypeFactory().getTypeInterfaceBean(coll,
+ KustvaktResource.class);
+ assertEquals(ResourceDao.class, AopUtils.getTargetClass(o));
+ BeansFactory.closeApplication();
+ }
+}