You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by si...@apache.org on 2009/11/20 09:06:24 UTC
svn commit: r882441 - in /labs/magma/trunk/lateconfig-impl: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/magma/ src/main/java/org/apache/magma/lateconfig/
src/main/resources/ src/test/ src/test/...
Author: simoneg
Date: Fri Nov 20 08:06:23 2009
New Revision: 882441
URL: http://svn.apache.org/viewvc?rev=882441&view=rev
Log:
LABS-365 : implementation for contextualized external configuration
Added:
labs/magma/trunk/lateconfig-impl/pom.xml
labs/magma/trunk/lateconfig-impl/src/
labs/magma/trunk/lateconfig-impl/src/main/
labs/magma/trunk/lateconfig-impl/src/main/java/
labs/magma/trunk/lateconfig-impl/src/main/java/org/
labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/
labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/
labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/
labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurationHook.aj
labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurator.java
labs/magma/trunk/lateconfig-impl/src/main/resources/
labs/magma/trunk/lateconfig-impl/src/test/
labs/magma/trunk/lateconfig-impl/src/test/java/
labs/magma/trunk/lateconfig-impl/src/test/java/org/
labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/
labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/
labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/
labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigBean.java
labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigTest.java
labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/OtherTriggerBean.java
labs/magma/trunk/lateconfig-impl/src/test/resources/
labs/magma/trunk/lateconfig-impl/src/test/resources/META-INF/
labs/magma/trunk/lateconfig-impl/src/test/resources/META-INF/lateconfig.properties
Added: labs/magma/trunk/lateconfig-impl/pom.xml
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/pom.xml?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/pom.xml (added)
+++ labs/magma/trunk/lateconfig-impl/pom.xml Fri Nov 20 08:06:23 2009
@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>magma-parent</artifactId>
+ <groupId>org.apache.magma</groupId>
+ <version>3</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.magma</groupId>
+ <artifactId>lateconfig-impl</artifactId>
+ <packaging>magma</packaging>
+ <name>Magma Late Configuration Implementation</name>
+ <version>0.0.3-SNAPSHOT</version>
+ <description> </description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.magma</groupId>
+ <artifactId>lateconfig-api</artifactId>
+ <version>0.0.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.magma</groupId>
+ <artifactId>foundation-beans</artifactId>
+ <version>0.0.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.magma</groupId>
+ <artifactId>foundation-basics</artifactId>
+ <version>0.0.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.7</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
Added: labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurationHook.aj
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurationHook.aj?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurationHook.aj (added)
+++ labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurationHook.aj Fri Nov 20 08:06:23 2009
@@ -0,0 +1,49 @@
+package org.apache.magma.lateconfig;
+
+import java.util.List;
+
+import org.apache.magma.basics.MagmaException;
+import org.aspectj.lang.reflect.MethodSignature;
+
+
+public aspect LateConfigurationHook {
+
+ public interface LateConfigurationSupport { }
+
+ declare parents: (@LateConfigurable *) implements LateConfigurationSupport;
+
+ public pointcut methodConfigurationTrigger() :
+ execution(@LateConfigurationTrigger public * LateConfigurationSupport+.*(..));
+ public pointcut constructorConfigurationTrigger() :
+ execution(@LateConfigurationTrigger LateConfigurationSupport+.new(..));
+
+ public pointcut configurableMethod() : execution(@LateConfigurable public * LateConfigurationSupport+.*(..));
+
+ private List<String> LateConfigurationSupport.configured = null;
+ private boolean LateConfigurationSupport.configuring = false;
+
+ after(LateConfigurationSupport bean) : constructorConfigurationTrigger() && this(bean) {
+ if (bean.configured != null || bean.configuring) return;
+ bean.configuring = true;
+ bean.configured = LateConfigurator.lateConfigure(bean);
+ }
+
+ before(LateConfigurationSupport bean) : methodConfigurationTrigger() && this(bean) {
+ if (bean.configured != null || bean.configuring) return;
+ bean.configuring = true;
+ bean.configured = LateConfigurator.lateConfigure(bean);
+ }
+
+ Object around(LateConfigurationSupport bean) : configurableMethod() && this(bean) {
+ if (bean.configured == null) return proceed(bean);
+ MethodSignature signature = (MethodSignature)thisJoinPoint.getSignature();
+ String methodname = signature.getName();
+ if (!bean.configured.contains(methodname)) return proceed(bean);
+ Class rt = signature.getReturnType();
+ if (rt.equals(Void.TYPE)) return null;
+ if (rt.isAssignableFrom(bean.getClass())) return bean;
+ throw new MagmaException("Don't know what to return after late configuration for method {0}, only void or same bean type are supported, not {1}", signature.toLongString(), rt);
+ }
+
+
+}
Added: labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurator.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurator.java?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurator.java (added)
+++ labs/magma/trunk/lateconfig-impl/src/main/java/org/apache/magma/lateconfig/LateConfigurator.java Fri Nov 20 08:06:23 2009
@@ -0,0 +1,172 @@
+package org.apache.magma.lateconfig;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.magma.basics.MagmaException;
+import org.apache.magma.basics.context.RunningContext;
+import org.apache.magma.basics.startup.CycleThreadLocal;
+import org.apache.magma.conversion.Converter;
+import org.apache.magma.conversion.Converters;
+import org.apache.magma.lateconfig.LateConfigurationHook.LateConfigurationSupport;
+import org.apache.magma.settings.ContextSettingsHolder;
+import org.apache.magma.settings.Settings;
+
+public class LateConfigurator {
+
+ protected static ContextSettingsHolder prodholder = new ContextSettingsHolder();
+ protected static CycleThreadLocal<ContextSettingsHolder> devholder = new CycleThreadLocal<ContextSettingsHolder>();
+
+ public static List<String> lateConfigure(LateConfigurationSupport bean) {
+ ContextSettingsHolder holder = initSettings();
+ RunningContext.get().push(bean.getClass());
+ String[] prop = null;
+ try {
+ List<String> ret = new ArrayList<String>();
+ Class<? extends LateConfigurationSupport> clazz = bean.getClass();
+ // TODO cache configurable methods
+ Method[] methods = clazz.getMethods();
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(LateConfigurable.class)) {
+ String keyname = method.getName();
+ if (keyname.startsWith("set")) {
+ keyname = keyname.substring(3);
+ }
+ prop = null;
+ prop = holder.getEntry(keyname);
+ if (prop == null) continue;
+ // TODO cache this conversion
+ Class<?>[] types = method.getParameterTypes();
+ Object[] params = new Object[types.length];
+ if (types.length > 0) {
+ // Special case of a single string
+ if (types.length == 1 && types[0].equals(String.class)) {
+ params[0] = prop[prop.length - 1];
+ } else {
+ String val = prop[prop.length - 1];
+ String[] strparams = parseArguments(val, prop);
+ // TODO how to handle overridden methods?
+ if (strparams.length != types.length) throw new MagmaException("Wrong number of parameters for late config of {0},{1}, expected {2} but found {3} in {4}", bean.getClass(), method.getName(), types.length, strparams.length, Arrays.toString(prop));
+ for (int i = 0; i < types.length; i++) {
+ Converter<?> converter = Converters.getConverterFor(types[i]);
+ if (converter == null) {
+ throw new MagmaException("Cannot find a converter for {0}, needed for late configuration of {1}", types[i], Arrays.toString(prop));
+ }
+ params[i] = converter.from(strparams[i]);
+ }
+ }
+ }
+ try {
+ method.invoke(bean, params);
+ ret.add(method.getName());
+ } catch (IllegalArgumentException e) {
+ throw new MagmaException(e, "There has been an error calling {0}.{1} using late configuration {2}", method.getDeclaringClass(), method.getName(), Arrays.toString(prop));
+ } catch (IllegalAccessException e) {
+ throw new MagmaException(e, "Method {0}.{1} is not accessible", method.getDeclaringClass(), method.getName());
+ } catch (InvocationTargetException e) {
+ throw new MagmaException(e, "There has been an error calling {0}.{1} using late configuration {2}", method.getDeclaringClass(), method.getName(), Arrays.toString(prop));
+ }
+ }
+ }
+ return ret;
+ } catch (Exception e) {
+ if (prop != null) {
+ throw new MagmaException(e, "Error while executing late config for {0}, on line {1}", bean.getClass(), Arrays.toString(prop));
+ } else {
+ throw new MagmaException(e, "Error while executing late config for {0}", bean.getClass());
+ }
+ } finally {
+ RunningContext.get().popClass();
+ }
+ }
+
+ protected static String[] parseArguments(String val, String[] props) {
+ String[] strparams = val.split(",");
+ // Let's try to handle string in quotes
+ int quoteindex = -1;
+ do {
+ quoteindex = -1;
+ int quotedcount = 0;
+ boolean closed = false;
+ for (int i = 0; i < strparams.length; i++) {
+ if (quoteindex == -1) {
+ if (strparams[i].startsWith("\"")) {
+ strparams[i] = strparams[i].substring(1);
+ quoteindex = i;
+ }
+ } else {
+ if (strparams[i].endsWith("\"")) {
+ closed = true;
+ strparams[i] = strparams[i].substring(0, strparams[i].length() - 1);
+ }
+ quotedcount++;
+ strparams[quoteindex] += "," + strparams[i];
+ strparams[i] = null;
+ if (closed) break;
+ }
+ }
+ if (quoteindex != -1 && !closed) throw new MagmaException("Unclosed \" in lateconfig.properties {0}", Arrays.toString(props));
+ String[] nstrparams = new String[strparams.length - quotedcount];
+ int k = 0;
+ for (int i = 0; i < strparams.length; i++) {
+ if (strparams[i] != null) nstrparams[k++] = strparams[i];
+ }
+ strparams = nstrparams;
+ } while (quoteindex > -1);
+ return strparams;
+ }
+
+ protected static ContextSettingsHolder initSettings() {
+ ContextSettingsHolder holder = null;
+ if (Settings.isDeveloperEnv()) {
+ holder = devholder.get();
+ if (holder == null) {
+ holder = new ContextSettingsHolder();
+ devholder.set(holder);
+ }
+ // No double check, cycle is thread specific
+ if (holder.isInited()) return holder;
+ holder.initing();
+ initHolder(holder);
+ } else {
+ holder = prodholder;
+ if (holder.isInited()) return holder;
+ holder.initing();
+ if (holder.isInited()) return holder;
+ initHolder(holder);
+ }
+ return holder;
+ }
+
+ protected static void initHolder(ContextSettingsHolder holder) {
+ ClassLoader loader = holder.getClass().getClassLoader();
+ Enumeration<URL> resources;
+ try {
+ resources = loader.getResources("META-INF/lateconfig.default.properties");
+ while (resources.hasMoreElements()) {
+ holder.overrideWith(resources.nextElement());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ try {
+ resources = loader.getResources("META-INF/lateconfig.default.properties.xml");
+ while (resources.hasMoreElements()) {
+ holder.overrideWith(resources.nextElement());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ holder.overrideWith(loader.getResource("META-INF/lateconfig.properties"));
+ holder.overrideWith(loader.getResource("META-INF/lateconfig.properties.xml"));
+ holder.inited();
+ }
+
+
+}
Added: labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigBean.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigBean.java?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigBean.java (added)
+++ labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigBean.java Fri Nov 20 08:06:23 2009
@@ -0,0 +1,59 @@
+package org.apache.magma.lateconfig;
+
+import java.lang.annotation.ElementType;
+
+@LateConfigurable
+public class LateConfigBean {
+
+ private String stringProp;
+ private String chained;
+ private String twostrings;
+ private int exoticInt;
+ private ElementType exoticEnum;
+
+ @LateConfigurationTrigger
+ public LateConfigBean() {
+
+ }
+
+ public String getStringProp() {
+ return stringProp;
+ }
+
+ @LateConfigurable
+ public void setStringProp(String stringProp) {
+ this.stringProp = stringProp;
+ }
+
+ public String getChained() {
+ return chained;
+ }
+
+ @LateConfigurable
+ public LateConfigBean setChained(String chained) {
+ this.chained = chained;
+ return this;
+ }
+
+ @LateConfigurable
+ public void setTwoStrings(String a, String b) {
+ twostrings = a + "-" + b;
+ }
+ public String getTwostrings() {
+ return twostrings;
+ }
+
+ @LateConfigurable
+ public void exotic(int i, ElementType ele) {
+ exoticEnum=ele;
+ exoticInt=i;
+ }
+
+ public int getExoticInt() {
+ return exoticInt;
+ }
+
+ public ElementType getExoticEnum() {
+ return exoticEnum;
+ }
+}
Added: labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigTest.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigTest.java?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigTest.java (added)
+++ labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/LateConfigTest.java Fri Nov 20 08:06:23 2009
@@ -0,0 +1,101 @@
+package org.apache.magma.lateconfig;
+
+import static org.junit.Assert.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+
+import org.apache.magma.basics.MagmaException;
+import org.apache.magma.basics.context.RunningContext;
+import org.apache.magma.basics.context.SubRunningContext;
+import org.junit.After;
+import org.junit.Test;
+
+public class LateConfigTest {
+
+ @Test
+ public void plainConfigure() throws Exception {
+ LateConfigBean bean = new LateConfigBean();
+ assertEquals("Simple configuration not working", "configured correctly", bean.getStringProp());
+ }
+
+ @After
+ public void cleanContext() {
+ RunningContext.cleanup();
+ }
+
+ @Test
+ public void differentContext() throws Exception {
+ SubRunningContext src = RunningContext.get();
+ src.push("incontext");
+
+ LateConfigBean bean = new LateConfigBean();
+ assertEquals("in context configuration not working", "configured in context", bean.getStringProp());
+ }
+
+ @Test
+ public void avoidSettingAgain() throws Exception {
+ LateConfigBean bean = new LateConfigBean();
+ assertEquals("Simple configuration not working", "configured correctly", bean.getStringProp());
+ bean.setStringProp("should not go");
+ assertEquals("Java set interception not working", "configured correctly", bean.getStringProp());
+ }
+
+ @Test
+ public void chainedSetters() throws Exception {
+ LateConfigBean bean = new LateConfigBean();
+ assertEquals("Simple configuration not working", "configured correctly", bean.getStringProp());
+ assertEquals("Simple configuration not working", "Configured Correctly", bean.getChained());
+ // If throws exception here it is not chaining
+ bean.setChained("no go").setStringProp("should not go");
+ assertEquals("Java set interception not working", "configured correctly", bean.getStringProp());
+ assertEquals("Java set interception not working", "Configured Correctly", bean.getChained());
+ }
+
+ @Test
+ public void otherTrigger() throws Exception {
+ OtherTriggerBean bean = new OtherTriggerBean();
+ assertEquals("Configured during constructor", "empty", bean.getStringProp());
+ String compute = bean.compute();
+ assertEquals("Not configured before trigger execution", "configured correctly", compute);
+ }
+
+ @Test
+ public void parseParamsTest() throws Exception {
+ String[] parsed = LateConfigurator.parseArguments("a,b", new String[0]);
+ assertEquals(2, parsed.length);
+ assertEquals("a", parsed[0]);
+ assertEquals("b", parsed[1]);
+ }
+
+ @Test
+ public void quotedParamsTest() throws Exception {
+ String[] parsed = LateConfigurator.parseArguments("\"a,b,c\",d", new String[0]);
+ assertEquals(2, parsed.length);
+ assertEquals("a,b,c", parsed[0]);
+ assertEquals("d", parsed[1]);
+ }
+
+ @Test
+ public void multipleParameters() throws Exception {
+ LateConfigBean bean = new LateConfigBean();
+ assertEquals("Multiple parameters not working correctly", "configured-it", bean.getTwostrings());
+ }
+
+ @Test(expected=MagmaException.class)
+ public void multipleParametersWithFewParameters() throws Exception {
+ SubRunningContext src = RunningContext.get();
+ src.push("wrongmulti");
+ LateConfigBean bean = new LateConfigBean();
+ }
+
+ @Test
+ public void exoticSetter() throws Exception {
+ SubRunningContext src = RunningContext.get();
+ src.push("inexotic");
+ LateConfigBean bean = new LateConfigBean();
+ assertEquals("Exotic set of int failed", 5, bean.getExoticInt());
+ assertEquals("Exotic set of enum failed", ElementType.METHOD, bean.getExoticEnum());
+ }
+
+}
Added: labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/OtherTriggerBean.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/OtherTriggerBean.java?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/OtherTriggerBean.java (added)
+++ labs/magma/trunk/lateconfig-impl/src/test/java/org/apache/magma/lateconfig/OtherTriggerBean.java Fri Nov 20 08:06:23 2009
@@ -0,0 +1,21 @@
+package org.apache.magma.lateconfig;
+
+@LateConfigurable
+public class OtherTriggerBean {
+ private String stringProp = "empty";
+
+ public String getStringProp() {
+ return stringProp;
+ }
+
+ @LateConfigurable
+ public void setStringProp(String stringProp) {
+ this.stringProp = stringProp;
+ }
+
+ @LateConfigurationTrigger
+ public String compute() {
+ return this.stringProp;
+ }
+
+}
Added: labs/magma/trunk/lateconfig-impl/src/test/resources/META-INF/lateconfig.properties
URL: http://svn.apache.org/viewvc/labs/magma/trunk/lateconfig-impl/src/test/resources/META-INF/lateconfig.properties?rev=882441&view=auto
==============================================================================
--- labs/magma/trunk/lateconfig-impl/src/test/resources/META-INF/lateconfig.properties (added)
+++ labs/magma/trunk/lateconfig-impl/src/test/resources/META-INF/lateconfig.properties Fri Nov 20 08:06:23 2009
@@ -0,0 +1,6 @@
+stringProp=configured correctly
+incontext.stringProp=configured in context
+chained=Configured Correctly
+twostrings=configured,it
+wrongmulti.twostrings=configured
+inexotic.exotic=5,METHOD
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org