missing dependencies

Change-Id: I9e70bced1255b3c4117cab2e6d0428168d72906a
diff --git a/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java b/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java
new file mode 100644
index 0000000..2fda630
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java
@@ -0,0 +1,53 @@
+package de.ids_mannheim.korap.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Created by hanl on 08.06.16.
+ */
+public class ConfigLoader {
+
+    private static final Logger jlog = LoggerFactory.getLogger(ConfigLoader.class);
+
+
+    private ConfigLoader () {}
+
+
+    public static InputStream loadConfigStream (String name) {
+        InputStream stream = null;
+        try {
+            File f = new File(System.getProperty("user.dir"), name);
+
+            if (f.exists()) {
+                jlog.info("Loading config '" + name + "' from file!");
+                stream = new FileInputStream(f);
+            }
+            else {
+                jlog.info("Loading config '" + name + "' from classpath!");
+                stream = ConfigLoader.class.getClassLoader().getResourceAsStream(
+                        name);
+            }
+        }
+        catch (IOException e) {
+            // do nothing
+        }
+        if (stream == null)
+            throw new RuntimeException("Config file '"+name+"' could not be loaded ...");
+        return stream;
+    }
+
+
+    public static Properties loadProperties (String name) throws IOException {
+        Properties p = new Properties();
+        p.load(loadConfigStream(name));
+        return p;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/config/KustvaktCacheable.java b/src/main/java/de/ids_mannheim/korap/config/KustvaktCacheable.java
new file mode 100644
index 0000000..1cbec73
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktCacheable.java
@@ -0,0 +1,107 @@
+package de.ids_mannheim.korap.config;
+
+import de.ids_mannheim.korap.utils.ServiceInfo;
+import de.ids_mannheim.korap.utils.StringUtils;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.PersistenceConfiguration;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+
+import java.io.InputStream;
+
+/**
+ * @author hanl
+ * @date 03/02/2016
+ */
+public abstract class KustvaktCacheable {
+
+    private static boolean loaded = false;
+    private String prefix;
+    private String name;
+
+    public KustvaktCacheable(String cache_name, String prefix) {
+        init();
+        if(!enabled())
+            createDefaultFileCache(cache_name);
+        this.prefix = prefix;
+        this.name = cache_name;
+    }
+
+    private static Cache getCache(String name) {
+        return CacheManager.getInstance().getCache(name);
+    }
+
+
+    private void createDefaultFileCache(String name) {
+        Cache default_cache = new Cache(
+                new CacheConfiguration(name, 20000)
+                        .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
+                        .eternal(false)
+                        .timeToLiveSeconds(20000)
+                        .timeToIdleSeconds(15000)
+                        .diskExpiryThreadIntervalSeconds(0)
+                        .persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.LOCALTEMPSWAP)));
+        if (!CacheManager.getInstance().cacheExists(name))
+            CacheManager.getInstance().addCache(default_cache);
+    }
+
+
+    public void init () {
+        if (!loaded) {
+            if (ServiceInfo.getInfo().getCacheable()) {
+                String file = "ehcache.xml";
+                InputStream in = ConfigLoader.loadConfigStream(file);
+                CacheManager.newInstance(in);
+                loaded = true;
+            } else {
+                CacheManager.create();
+            }
+        }
+    }
+
+    public boolean hasCacheEntry(Object key) {
+        return getCache(this.name).isKeyInCache(createKey(key.toString()));
+    }
+
+
+    public boolean enabled() {
+        // check that caching is enabled
+        return ServiceInfo.getInfo().getCacheable();
+    }
+
+    public Object getCacheValue(Object key) {
+        Element e = getCache(this.name).get(createKey(key.toString()));
+        if (e!= null)
+            return e.getObjectValue();
+        return null;
+    }
+
+    public long getCacheCreationTime(Object key) {
+        Element e = getCache(this.name).get(createKey(key.toString()));
+        if (e!= null)
+            return e.getCreationTime();
+        return -1;
+    }
+
+    public void storeInCache(Object key, Object value) {
+        getCache(this.name).put(new Element(createKey(key.toString()), value));
+    }
+
+    public void removeCacheEntry(Object key) {
+        getCache(this.name).remove(createKey(key.toString()));
+    }
+
+    public void clearCache() {
+        Cache c = getCache(this.name);
+        if (enabled()) {
+            c.removeAll();
+            c.clearStatistics();
+        }
+    }
+
+    private String createKey(String input) {
+        return StringUtils.toSHAHash(this.prefix+ "@" + input);
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java
new file mode 100644
index 0000000..7fe20c6
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java
@@ -0,0 +1,21 @@
+package de.ids_mannheim.korap.interfaces;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+
+import java.util.Map;
+
+/**
+ * Created by hanl on 08.06.16.
+ */
+public interface ValidatorIface {
+
+
+    Map<String, Object> validateMap (Map<String, Object> map);
+
+
+    String validateEntry (String input, String type)
+            throws KustvaktException;
+
+
+    boolean isValid (String input, String type);
+}
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java
new file mode 100644
index 0000000..8d420ec
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java
@@ -0,0 +1,109 @@
+package de.ids_mannheim.korap.interfaces.defaults;
+
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.ConfigLoader;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.ValidatorIface;
+import de.ids_mannheim.korap.web.utils.KustvaktMap;
+import org.apache.commons.validator.routines.*;
+import org.apache.commons.validator.routines.RegexValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Created by hanl on 09.06.16.
+ */
+public class ApacheValidator implements ValidatorIface {
+
+    private static Logger jlog = LoggerFactory.getLogger(ApacheValidator.class);
+
+    private static final String STRING_PATTERN ="^[\\.;:,&\\|@\\[\\]\\=\\*\\/\\/_()\\-0-9\\p{L}\\p{Space}]{0,1024}$";
+
+    private Map<String, RegexValidator> validators;
+
+    public ApacheValidator () throws IOException {
+        this.validators = load();
+    }
+
+    private static Map<String, RegexValidator> load () throws IOException {
+        Map<String, RegexValidator> validatorMap = new HashMap<>();
+        Properties p = ConfigLoader.loadProperties("validation.properties");
+
+        for (String property : p.stringPropertyNames()) {
+            if (property.startsWith("Validator")) {
+                String name = property.replace("Validator.", "");
+                RegexValidator v = new RegexValidator(p.get(property).toString());
+                validatorMap.put(name, v);
+            }
+        }
+        return validatorMap;
+    }
+
+
+
+    @Override
+    public Map<String, Object> validateMap (Map<String, Object> map) {
+        Map<String, Object> safeMap = new HashMap<>();
+        KustvaktMap kmap = new KustvaktMap(map);
+
+        if (map != null) {
+                loop : for (String key : kmap.keySet()) {
+                    Object value = kmap.getRaw(key);
+                    if (value instanceof List) {
+                        List list = (List) value;
+                        for (int i =0;i<list.size();i++) {
+                            if (!isValid(String.valueOf(list.get(i)), key))
+                                list.remove(i);
+                        }
+
+                        if (list.size() == 1)
+                            value = list.get(0);
+                        else
+                            value = list;
+                    } else {
+                        if (!isValid(kmap.get(key), key))
+                          continue loop;
+                    }
+                    safeMap.put(key, value);
+                }
+            }
+        return safeMap;
+    }
+
+
+    @Override
+    public String validateEntry (String input, String type)
+            throws KustvaktException {
+        if (!isValid(input, type))
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
+                    "Entry did not validate for type '" + type + "'", input);
+        return input;
+    }
+
+    @Override
+    public boolean isValid(String input, String type) {
+        boolean valid = false;
+        RegexValidator validator = this.validators.get(type);
+        if (validator != null) {
+            valid = validator.isValid(input);
+        } else {
+            if (Attributes.EMAIL.equals(type)) {
+                valid = EmailValidator.getInstance().isValid(input);
+            } else if ("date".equals(type)) {
+                valid = DateValidator.getInstance().isValid(input);
+            } else if ("string".equals(type) && !this.validators.containsKey("string")) {
+                RegexValidator regex = new RegexValidator(STRING_PATTERN);
+                valid = regex.isValid(input);
+            }
+            else
+                return this.isValid(input, "string");
+        }
+        jlog.debug("validating entry '{}' of type '{}': {}",
+                input, type, valid ? "Is valid!" : "Is not valid!");
+        return valid;
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
index 1184ac8..51ec505 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
@@ -89,7 +89,6 @@
                     "token type not defined or found", "token_type");
 
         TokenContext context = provider.getTokenContext(token);
-        System.out.println("CONTEXT "+ context.toResponse());
         if (context != null && TimeUtils.isExpired(context.getExpirationTime()))
             throw new KustvaktException(StatusCodes.EXPIRED);
 
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java
index ea64938..ff1a23b 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java
@@ -44,12 +44,13 @@
         ClientResponse response = resource().path(getAPIVersion()).path("oauth2")
                 .path("register")
                 .queryParam("redirect_url", "korap.ids-mannheim.de/redirect")
+                .queryParam("application_name", "Kustvakt test")
                 .header("Host", "korap.ids-mannheim.de")
                 .header(Attributes.AUTHORIZATION, auth)
                 .post(ClientResponse.class);
 
         JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
-        System.out.println(node);
+
 
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());