diff --git a/memory-impl/impl/pom.xml b/memory-impl/impl/pom.xml
index 5ff2ee3..0faa726 100644
--- a/memory-impl/impl/pom.xml
+++ b/memory-impl/impl/pom.xml
@@ -27,6 +27,11 @@
org.sakaiproject
+ sakai-component-api
+ ${sakai.version}
+
+
+ org.sakaiproject
sakai-entity-api
${sakai.version}
diff --git a/memory-impl/impl/src/java/org/sakaiproject/memory/impl/BasicMemoryService.java b/memory-impl/impl/src/java/org/sakaiproject/memory/impl/BasicMemoryService.java
index e386d4c..d58c8c0 100644
--- a/memory-impl/impl/src/java/org/sakaiproject/memory/impl/BasicMemoryService.java
+++ b/memory-impl/impl/src/java/org/sakaiproject/memory/impl/BasicMemoryService.java
@@ -39,6 +39,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.authz.api.AuthzGroupService;
import org.sakaiproject.authz.api.SecurityService;
+import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.event.api.Event;
import org.sakaiproject.event.api.EventTrackingService;
@@ -93,7 +94,12 @@ public abstract class BasicMemoryService implements MemoryService, Observer
* @return the AuthzGroupService collaborator.
*/
protected abstract AuthzGroupService authzGroupService();
-
+
+ /**
+ * @return the ServerConfigurationService collaborator
+ */
+ protected abstract ServerConfigurationService serverConfigurationService();
+
/**********************************************************************************************************************************************************************************************************************************************************
* Configuration
*********************************************************************************************************************************************************************************************************************************************************/
@@ -469,10 +475,16 @@ public abstract class BasicMemoryService implements MemoryService, Observer
return cacheManager.getEhcache(name);
}
cacheManager.addCache(name);
- return cacheManager.getEhcache(name);
-
-
+ Ehcache cache = cacheManager.getEhcache(name);
+ // Not look for any custom configuration.
+ String config = serverConfigurationService().getString(name);
+ if (config != null && config.length() > 0) {
+ M_log.debug("Found configuration for cache: "+ name+ " of: "+ config);
+ new CacheInitializer().configure(config).initialize(
+ cache.getCacheConfiguration());
+ }
+ return cache;
/*
diff --git a/memory-impl/impl/src/java/org/sakaiproject/memory/impl/CacheInitializer.java b/memory-impl/impl/src/java/org/sakaiproject/memory/impl/CacheInitializer.java
new file mode 100644
index 0000000..ea5dd05
--- /dev/null
+++ b/memory-impl/impl/src/java/org/sakaiproject/memory/impl/CacheInitializer.java
@@ -0,0 +1,128 @@
+package org.sakaiproject.memory.impl;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.ehcache.config.CacheConfiguration;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Utility class to configure a cache. Could have used common beanutils but
+ * didn't want another library.
+ *
+ * @author buckett
+ *
+ */
+public class CacheInitializer {
+
+ private static final Log log = LogFactory.getLog(CacheInitializer.class);
+
+ private Map configMap;
+
+ public CacheInitializer() {
+
+ }
+
+ /**
+ * Set the configuration that needs to be set on the cache.
+ *
+ * @param config
+ * The unsplit configuration. Eg:
+ * "timeToLiveSeconds=400,timeToIdleSeconds=100"
+ * @return This object.
+ */
+ public CacheInitializer configure(String config) {
+ configMap = new HashMap();
+ String[] configParts = config.split(",");
+ for (String part : configParts) {
+ String[] splitParts = part.split("=", 2);
+ if (splitParts.length == 2) {
+ String key = splitParts[0];
+ String value = splitParts[1];
+ configMap.put(key, value);
+ } else {
+ log.warn("Couldn't parse cache config of: " + part);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Configure
+ *
+ * @param cacheConfig
+ * @return
+ */
+ public CacheInitializer initialize(CacheConfiguration cacheConfig) {
+ if (configMap == null) {
+ throw new IllegalStateException(
+ "You must configure the initializer first.");
+ }
+ Method[] methods = cacheConfig.getClass().getMethods();
+ for (Method method : methods) {
+ if (Modifier.isPublic(method.getModifiers())
+ && method.getName().startsWith("set")
+ && method.getParameterTypes().length == 1) {
+ // Ok we can handle this method.
+ String key = Character.toLowerCase(method.getName().charAt(
+ "set".length()))
+ + method.getName().substring("set".length() + 1);
+ log.debug("Looking in config map for: " + key);
+ String value = configMap.get(key);
+ if (value != null) {
+ Class clazz = method.getParameterTypes()[0];
+ log.debug("Need to convert to :" + clazz);
+ Object obj = covertValue(value, clazz);
+
+ if (obj != null) {
+ invokeMethod(method, cacheConfig, obj);
+ }
+
+ }
+
+ }
+ }
+ return this;
+ }
+
+ private Object covertValue(String value, Class clazz) {
+ Object obj = null;
+ try {
+ if (String.class.equals(clazz)) {
+ obj = value;
+ } else if (Integer.class.equals(clazz) || int.class.equals(clazz)) {
+ obj = Integer.valueOf(value);
+ } else if (Boolean.class.equals(clazz)
+ || boolean.class.equals(clazz)) {
+ obj = Boolean.valueOf(value);
+ } else if (Long.class.equals(clazz) || long.class.equals(clazz)) {
+ obj = Long.valueOf(value);
+ } else if (Float.class.equals(clazz) || float.class.equals(clazz)) {
+ obj = Float.valueOf(value);
+ } else if (Double.class.equals(clazz) || double.class.equals(clazz)) {
+ obj = Double.valueOf(value);
+ } else if (Character.class.equals(clazz)
+ || char.class.equals(clazz)) {
+ obj = Character.valueOf(value.charAt(0));
+ } else {
+ log.debug("Can't convert to :" + clazz);
+ }
+ } catch (NumberFormatException nfe) {
+ log.debug("Ignored bad number: " + value);
+ }
+ return obj;
+ }
+
+ private void invokeMethod(Method method, Object obj, Object value) {
+ try {
+ method.invoke(obj, value);
+ } catch (Exception e) {
+ log.debug(e);
+ }
+ }
+
+}
diff --git a/memory-impl/impl/src/java/org/sakaiproject/memory/impl/MemoryServiceTest.java b/memory-impl/impl/src/java/org/sakaiproject/memory/impl/MemoryServiceTest.java
index 05c3584..39ec259 100644
--- a/memory-impl/impl/src/java/org/sakaiproject/memory/impl/MemoryServiceTest.java
+++ b/memory-impl/impl/src/java/org/sakaiproject/memory/impl/MemoryServiceTest.java
@@ -23,6 +23,7 @@ package org.sakaiproject.memory.impl;
import org.sakaiproject.authz.api.AuthzGroupService;
import org.sakaiproject.authz.api.SecurityService;
+import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.event.api.EventTrackingService;
import org.sakaiproject.event.api.UsageSessionService;
import org.sakaiproject.memory.api.Cache;
@@ -89,5 +90,11 @@ public class MemoryServiceTest extends BasicMemoryService
return null;
}
+ @Override
+ protected ServerConfigurationService serverConfigurationService() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
diff --git a/memory-impl/impl/src/test/org/sakai/memory/impl/test/MemoryServiceTest.java b/memory-impl/impl/src/test/org/sakai/memory/impl/test/MemoryServiceTest.java
index 190b527..79fc7b5 100644
--- a/memory-impl/impl/src/test/org/sakai/memory/impl/test/MemoryServiceTest.java
+++ b/memory-impl/impl/src/test/org/sakai/memory/impl/test/MemoryServiceTest.java
@@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.authz.api.AuthzGroupService;
import org.sakaiproject.authz.api.SecurityService;
+import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.event.api.EventTrackingService;
import org.sakaiproject.event.api.UsageSessionService;
import org.sakaiproject.memory.api.Cache;
@@ -49,6 +50,7 @@ public class MemoryServiceTest extends TestCase
private AuthzGroupService authzGroupService;
private BasicMemoryService basicMemoryService;
private CacheManager cacheManager;
+ private ServerConfigurationService serverConfigurationService;
/**
* @param name
@@ -67,9 +69,10 @@ public class MemoryServiceTest extends TestCase
eventTrackingService = new MockEventTrackingService();
securityService = new MockSecurityService();
+ serverConfigurationService = new MockServerConfigurationService();
usageSessionService = new MockUsageSessionService();
authzGroupService = new MockAuthzGroupService();
- basicMemoryService = new MockBasicMemoryService(eventTrackingService, securityService, usageSessionService, authzGroupService );
+ basicMemoryService = new MockBasicMemoryService(eventTrackingService, securityService, usageSessionService, authzGroupService, serverConfigurationService );
cacheManager = new CacheManager(this.getClass().getResourceAsStream("ehcache.xml"));
basicMemoryService.setCacheManager(cacheManager);
}
diff --git a/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockBasicMemoryService.java b/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockBasicMemoryService.java
index b6c42a7..47b8e34 100644
--- a/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockBasicMemoryService.java
+++ b/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockBasicMemoryService.java
@@ -23,6 +23,7 @@ package org.sakai.memory.impl.test;
import org.sakaiproject.authz.api.AuthzGroupService;
import org.sakaiproject.authz.api.SecurityService;
+import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.event.api.EventTrackingService;
import org.sakaiproject.event.api.UsageSessionService;
import org.sakaiproject.memory.impl.BasicMemoryService;
@@ -38,16 +39,18 @@ public class MockBasicMemoryService extends BasicMemoryService
private SecurityService securityService;
private UsageSessionService usageSessionService;
private AuthzGroupService authzGroupService;
+ private ServerConfigurationService serverConfigurationService;
/**
*
*/
- public MockBasicMemoryService(EventTrackingService eventTrackingService, SecurityService securityService, UsageSessionService usageSessionService, AuthzGroupService authzGroupService)
+ public MockBasicMemoryService(EventTrackingService eventTrackingService, SecurityService securityService, UsageSessionService usageSessionService, AuthzGroupService authzGroupService, ServerConfigurationService serverConfigurationService)
{
this.eventTrackingService = eventTrackingService;
this.securityService = securityService;
this.usageSessionService = usageSessionService;
this.authzGroupService = authzGroupService;
+ this.serverConfigurationService = serverConfigurationService;
}
/* (non-Javadoc)
@@ -83,4 +86,9 @@ public class MockBasicMemoryService extends BasicMemoryService
return authzGroupService;
}
+ @Override
+ protected ServerConfigurationService serverConfigurationService() {
+ return serverConfigurationService;
+ }
+
}
diff --git a/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockServerConfigurationService.java b/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockServerConfigurationService.java
new file mode 100644
index 0000000..5b6e228
--- /dev/null
+++ b/memory-impl/impl/src/test/org/sakai/memory/impl/test/MockServerConfigurationService.java
@@ -0,0 +1,136 @@
+package org.sakai.memory.impl.test;
+
+import java.util.List;
+import java.util.Map;
+
+import org.sakaiproject.component.api.ServerConfigurationService;
+
+public class MockServerConfigurationService implements
+ ServerConfigurationService {
+
+ public String getAccessPath() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getAccessUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean getBoolean(String name, boolean dflt) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public List getDefaultTools(String category) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getGatewaySiteId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getHelpUrl(String helpContext) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int getInt(String name, int dflt) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public String getLoggedOutUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getPortalUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getSakaiHomePath() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getServerId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getServerIdInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getServerInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getServerName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getServerUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getString(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getString(String name, String dflt) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String[] getStrings(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List getToolCategories(String category) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Map> getToolCategoriesAsMap(String category) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List getToolOrder(String category) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Map getToolToCategoryMap(String category) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getToolUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List getToolsRequired(String category) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getUserHomeUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/memory-impl/impl/src/test/org/sakai/memory/impl/test/TestCacheInitializer.java b/memory-impl/impl/src/test/org/sakai/memory/impl/test/TestCacheInitializer.java
new file mode 100644
index 0000000..c04ac2b
--- /dev/null
+++ b/memory-impl/impl/src/test/org/sakai/memory/impl/test/TestCacheInitializer.java
@@ -0,0 +1,49 @@
+package org.sakai.memory.impl.test;
+
+import org.sakaiproject.memory.impl.CacheInitializer;
+
+import junit.framework.TestCase;
+import net.sf.ehcache.config.CacheConfiguration;
+
+public class TestCacheInitializer extends TestCase {
+
+ private CacheConfiguration config;
+ private CacheInitializer initializer;
+
+ public void setUp() {
+ config = new CacheConfiguration();
+ initializer = new CacheInitializer();
+ }
+
+ public void testSingleConfig() {
+ initializer.configure("timeToLiveSeconds=400").initialize(config);
+ assertEquals(400, config.getTimeToLiveSeconds());
+ }
+
+ public void testMultipleConfig() {
+ initializer.configure("timeToLiveSeconds=300,timeToIdleSeconds=150")
+ .initialize(config);
+ assertEquals(300, config.getTimeToLiveSeconds());
+ assertEquals(150, config.getTimeToIdleSeconds());
+ }
+
+ public void testDuplicateConfig() {
+ initializer.configure("timeToLiveSeconds=300,timeToIdleSeconds=150,timeToLiveSeconds=10")
+ .initialize(config);
+ assertEquals(10, config.getTimeToLiveSeconds());
+ assertEquals(150, config.getTimeToIdleSeconds());
+ }
+
+ public void testBadKey() {
+ initializer.configure("doesNotExist=300,timeToIdleSeconds=150")
+ .initialize(config);
+ assertEquals(150, config.getTimeToIdleSeconds());
+ }
+
+ public void testBadValue() {
+ initializer.configure("timeToLiveSeconds=300a,timeToIdleSeconds=150")
+ .initialize(config);
+ assertEquals(150, config.getTimeToIdleSeconds());
+ }
+
+}
diff --git a/memory-impl/pack/src/webapp/WEB-INF/components.xml b/memory-impl/pack/src/webapp/WEB-INF/components.xml
index 3d4e3d0..7137838 100644
--- a/memory-impl/pack/src/webapp/WEB-INF/components.xml
+++ b/memory-impl/pack/src/webapp/WEB-INF/components.xml
@@ -13,6 +13,7 @@
+
false