You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2010/04/24 23:30:30 UTC
svn commit: r937704 - in /incubator/shiro/trunk/core/src:
main/java/org/apache/shiro/config/ test/java/org/apache/shiro/config/
Author: lhazlewood
Date: Sat Apr 24 21:30:30 2010
New Revision: 937704
URL: http://svn.apache.org/viewvc?rev=937704&view=rev
Log:
SHIRO-152 - added ability to configure sets, lists and maps. Added test cases for validation
Modified:
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java
incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/ReflectionBuilderTest.java
incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java?rev=937704&r1=937703&r2=937704&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java Sat Apr 24 21:30:30 2010
@@ -22,12 +22,12 @@ import org.apache.commons.beanutils.Bean
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.shiro.util.ClassUtils;
import org.apache.shiro.util.Nameable;
+import org.apache.shiro.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.PropertyDescriptor;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
/**
@@ -49,6 +49,7 @@ public class ReflectionBuilder {
private static final String OBJECT_REFERENCE_BEGIN_TOKEN = "$";
private static final String ESCAPED_OBJECT_REFERENCE_BEGIN_TOKEN = "\\$";
private static final String GLOBAL_PROPERTY_PREFIX = "shiro";
+ private static final char MAP_KEY_VALUE_DELIMITER = ':';
protected Map objects;
@@ -170,7 +171,7 @@ public class ReflectionBuilder {
} else if (instance == null) {
String msg = "Configuration error. Specified object [" + name + "] with property [" +
property + "] without first defining that object's class. Please first " +
- "specify the class property first, e.g. myObject.class = fully_qualified_class_name " +
+ "specify the class property first, e.g. myObject = fully_qualified_class_name " +
"and then define additional properties.";
throw new IllegalArgumentException(msg);
@@ -205,17 +206,129 @@ public class ReflectionBuilder {
return value;
}
- protected void applyProperty(Object object, String propertyName, String stringValue) {
+ protected Object resolveReference(String reference) {
+ String id = getId(reference);
+ log.debug("Encountered object reference '{}'. Looking up object with id '{}'", reference, id);
+ return getReferencedObject(id);
+ }
- Object value;
+ protected boolean isSetProperty(Object object, String propertyName) {
+ try {
+ PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(object, propertyName);
+ Class clazz = descriptor.getPropertyType();
+ return Set.class.isAssignableFrom(clazz);
+ } catch (Exception e) {
+ String msg = "Unable to determine if property [" + propertyName + "] represents a java.util.Set";
+ throw new ConfigurationException(msg, e);
+ }
+ }
+
+ protected Set<?> toSet(String sValue) {
+ String[] tokens = StringUtils.split(sValue);
+ if (tokens == null || tokens.length <= 0) {
+ return null;
+ }
+ Set<String> setTokens = new LinkedHashSet<String>(Arrays.asList(tokens));
+
+ //now convert into correct values and/or references:
+ Set<Object> values = new LinkedHashSet<Object>(setTokens.size());
+ for (String token : setTokens) {
+ Object value = resolveValue(token);
+ values.add(value);
+ }
+ return values;
+ }
+ protected boolean isListProperty(Object object, String propertyName) {
+ try {
+ PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(object, propertyName);
+ Class clazz = descriptor.getPropertyType();
+ return List.class.isAssignableFrom(clazz);
+ } catch (Exception e) {
+ String msg = "Unable to determine if property [" + propertyName + "] represents a java.util.List";
+ throw new ConfigurationException(msg, e);
+ }
+ }
+
+ protected List<?> toList(String sValue) {
+ String[] tokens = StringUtils.split(sValue);
+ if (tokens == null || tokens.length <= 0) {
+ return null;
+ }
+
+ //now convert into correct values and/or references:
+ List<Object> values = new ArrayList<Object>(tokens.length);
+ for (String token : tokens) {
+ Object value = resolveValue(token);
+ values.add(value);
+ }
+ return values;
+ }
+
+ protected boolean isMapProperty(Object object, String propertyName) {
+ try {
+ PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(object, propertyName);
+ Class clazz = descriptor.getPropertyType();
+ return Map.class.isAssignableFrom(clazz);
+ } catch (Exception e) {
+ String msg = "Unable to determine if property [" + propertyName + "] represents a java.util.Map";
+ throw new ConfigurationException(msg, e);
+ }
+ }
+
+ protected Map<?, ?> toMap(String sValue) {
+ String[] tokens = StringUtils.split(sValue, StringUtils.DEFAULT_DELIMITER_CHAR,
+ StringUtils.DEFAULT_QUOTE_CHAR, StringUtils.DEFAULT_QUOTE_CHAR, true, true);
+ if (tokens == null || tokens.length <= 0) {
+ return null;
+ }
+
+ Map<String, String> mapTokens = new LinkedHashMap<String, String>(tokens.length);
+ for (String token : tokens) {
+ String[] kvPair = StringUtils.split(token, ':');
+ if (kvPair == null || kvPair.length != 2) {
+ String msg = "Map property value [" + sValue + "] contained key-value pair token [" +
+ token + "] that does not properly split to a single key and pair. This must be the " +
+ "case for all map entries.";
+ throw new ConfigurationException(msg);
+ }
+ mapTokens.put(kvPair[0], kvPair[1]);
+ }
+
+ //now convert into correct values and/or references:
+ Map<Object, Object> map = new LinkedHashMap<Object, Object>(mapTokens.size());
+ for (Map.Entry<String, String> entry : mapTokens.entrySet()) {
+ Object key = resolveValue(entry.getKey());
+ Object value = resolveValue(entry.getValue());
+ map.put(key, value);
+ }
+ return map;
+ }
+
+ protected Object resolveValue(String stringValue) {
+ Object value;
if (isReference(stringValue)) {
- String id = getId(stringValue);
- log.debug("Encountered object reference '{}'. Looking up object with id '{}'", stringValue, id);
- value = getReferencedObject(id);
+ value = resolveReference(stringValue);
} else {
value = unescapeIfNecessary(stringValue);
}
+ return value;
+ }
+
+
+ protected void applyProperty(Object object, String propertyName, String stringValue) {
+
+ Object value;
+
+ if (isSetProperty(object, propertyName)) {
+ value = toSet(stringValue);
+ } else if (isListProperty(object, propertyName)) {
+ value = toList(stringValue);
+ } else if (isMapProperty(object, propertyName)) {
+ value = toMap(stringValue);
+ } else {
+ value = resolveValue(stringValue);
+ }
try {
if (log.isTraceEnabled()) {
Modified: incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java?rev=937704&r1=937703&r2=937704&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java (original)
+++ incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java Sat Apr 24 21:30:30 2010
@@ -18,17 +18,25 @@
*/
package org.apache.shiro.config;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* @author Les Hazlewood
* @since Aug 5, 2008 10:17:37 AM
*/
-public class CompositeBean
-{
+public class CompositeBean {
+
private String stringProp;
private boolean booleanProp;
private int intProp;
private SimpleBean simpleBean;
+ private Set<SimpleBean> simpleBeanSet;
+ private List<SimpleBean> simpleBeanList;
+ private Map<String, SimpleBean> simpleBeanMap;
+
public CompositeBean() {
}
@@ -63,4 +71,28 @@ public class CompositeBean
public void setSimpleBean(SimpleBean simpleBean) {
this.simpleBean = simpleBean;
}
+
+ public Set<SimpleBean> getSimpleBeanSet() {
+ return simpleBeanSet;
+ }
+
+ public void setSimpleBeanSet(Set<SimpleBean> simpleBeanSet) {
+ this.simpleBeanSet = simpleBeanSet;
+ }
+
+ public List<SimpleBean> getSimpleBeanList() {
+ return simpleBeanList;
+ }
+
+ public void setSimpleBeanList(List<SimpleBean> simpleBeanList) {
+ this.simpleBeanList = simpleBeanList;
+ }
+
+ public Map<String, SimpleBean> getSimpleBeanMap() {
+ return simpleBeanMap;
+ }
+
+ public void setSimpleBeanMap(Map<String, SimpleBean> simpleBeanMap) {
+ this.simpleBeanMap = simpleBeanMap;
+ }
}
Modified: incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/ReflectionBuilderTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/ReflectionBuilderTest.java?rev=937704&r1=937703&r2=937704&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/ReflectionBuilderTest.java (original)
+++ incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/ReflectionBuilderTest.java Sat Apr 24 21:30:30 2010
@@ -18,14 +18,15 @@
*/
package org.apache.shiro.config;
+import org.apache.shiro.util.CollectionUtils;
+import org.junit.Test;
+
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import static org.junit.Assert.*;
-import org.junit.Test;
-import org.apache.shiro.config.ConfigurationException;
-import org.apache.shiro.config.ReflectionBuilder;
-import org.apache.shiro.config.UnresolveableReferenceException;
/**
* @author Les Hazlewood
@@ -105,4 +106,81 @@ public class ReflectionBuilderTest {
ReflectionBuilder builder = new ReflectionBuilder();
builder.buildObjects(defs);
}
+
+ @Test
+ public void testSetProperty() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean1", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean2", "org.apache.shiro.config.SimpleBean");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBeanSet", "$simpleBean1, $simpleBean2, $simpleBean2");
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ CompositeBean cBean = (CompositeBean) objects.get("compositeBean");
+ assertNotNull(cBean);
+ Set<SimpleBean> simpleBeans = cBean.getSimpleBeanSet();
+ assertNotNull(simpleBeans);
+ assertEquals(2, simpleBeans.size());
+ }
+
+ @Test
+ public void testListProperty() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean1", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean2", "org.apache.shiro.config.SimpleBean");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBeanList", "$simpleBean1, $simpleBean2, $simpleBean2");
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ CompositeBean cBean = (CompositeBean) objects.get("compositeBean");
+ assertNotNull(cBean);
+ List<SimpleBean> simpleBeans = cBean.getSimpleBeanList();
+ assertNotNull(simpleBeans);
+ assertEquals(3, simpleBeans.size());
+ }
+
+ @Test
+ public void testMapProperty() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean1", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean2", "org.apache.shiro.config.SimpleBean");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBeanMap", "simpleBean1:$simpleBean1, simpleBean2:$simpleBean2");
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ CompositeBean cBean = (CompositeBean) objects.get("compositeBean");
+ assertNotNull(cBean);
+ Map map = cBean.getSimpleBeanMap();
+ assertNotNull(map);
+ assertEquals(2, map.size());
+ Object value = map.get("simpleBean1");
+ assertTrue(value instanceof SimpleBean);
+ value = map.get("simpleBean2");
+ assertTrue(value instanceof SimpleBean);
+ }
+
+ @Test
+ public void testNestedListProperty() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean1", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean2", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean3", "org.apache.shiro.config.SimpleBean");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBean", "$simpleBean1");
+ defs.put("compositeBean.simpleBean.simpleBeans", "$simpleBean2, $simpleBean3");
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ CompositeBean cBean = (CompositeBean) objects.get("compositeBean");
+ assertNotNull(cBean);
+ SimpleBean nested = cBean.getSimpleBean();
+ assertNotNull(nested);
+ List<SimpleBean> children = nested.getSimpleBeans();
+ assertNotNull(children);
+ assertEquals(2, children.size());
+ }
+
}
Modified: incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java?rev=937704&r1=937703&r2=937704&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java (original)
+++ incubator/shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java Sat Apr 24 21:30:30 2010
@@ -18,16 +18,19 @@
*/
package org.apache.shiro.config;
+import java.util.List;
+
/**
* @author Les Hazlewood
* @since Aug 5, 2008 10:18:01 AM
*/
-public class SimpleBean
-{
+public class SimpleBean {
private String stringProp = null;
private int intProp;
+ private List<SimpleBean> simpleBeans;
+
public SimpleBean() {
}
@@ -46,4 +49,12 @@ public class SimpleBean
public void setIntProp(int intProp) {
this.intProp = intProp;
}
+
+ public List<SimpleBean> getSimpleBeans() {
+ return simpleBeans;
+ }
+
+ public void setSimpleBeans(List<SimpleBean> simpleBeans) {
+ this.simpleBeans = simpleBeans;
+ }
}