Author: lhazlewood
Date: Sat Jan 7 03:36:57 2012
New Revision: 1228564
URL: http://svn.apache.org/viewvc?rev=1228564&view=rev
Log:
SHIRO-305: INI config now supports setting map/array referenced values, e.g.
bean.aMapProperty[mapKey] = mapValue
Added:
shiro/trunk/core/src/test/groovy/org/apache/shiro/config/
shiro/trunk/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
Removed:
shiro/trunk/core/src/test/java/org/apache/shiro/config/ReflectionBuilderTest.java
Modified:
shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java
shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java
Modified:
shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java?rev=1228564&r1=1228563&r2=1228564&view=diff
==============================================================================
---
shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
(original)
+++
shiro/trunk/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
Sat Jan 7 03:36:57 2012
@@ -54,6 +54,8 @@ public class ReflectionBuilder {
private static final String NULL_VALUE_TOKEN = "null";
private static final String EMPTY_STRING_VALUE_TOKEN = "\"\"";
private static final char STRING_VALUE_DELIMETER = '"';
+ private static final char MAP_PROPERTY_BEGIN_TOKEN = '[';
+ private static final char MAP_PROPERTY_END_TOKEN = ']';
private Map<String, ?> objects;
@@ -361,6 +363,119 @@ public class ReflectionBuilder {
return stringValue;
}
}
+
+ protected void applyProperty(Object object, String propertyPath, Object
value) {
+
+ int mapBegin = propertyPath.indexOf(MAP_PROPERTY_BEGIN_TOKEN);
+ int mapEnd = -1;
+ String mapPropertyPath = null;
+ String keyString = null;
+
+ String remaining = null;
+
+ if (mapBegin >= 0) {
+ //a map is being referenced in the overall property path. Find
just the map's path:
+ mapPropertyPath = propertyPath.substring(0, mapBegin);
+ //find the end of the map reference:
+ mapEnd = propertyPath.indexOf(MAP_PROPERTY_END_TOKEN, mapBegin);
+ //find the token in between the [ and the ] (the map/array key or
index):
+ keyString = propertyPath.substring(mapBegin+1, mapEnd);
+
+ //find out if there is more path reference to follow. If not,
we're at a terminal of the OGNL expression
+ if (propertyPath.length() > (mapEnd+1)) {
+ remaining = propertyPath.substring(mapEnd+1);
+ if (remaining.startsWith(".")) {
+ remaining = StringUtils.clean(remaining.substring(1));
+ }
+ }
+ }
+
+ if (remaining == null) {
+ //we've terminated the OGNL expression. Check to see if we're
assigning a property or a map entry:
+ if (keyString == null) {
+ //not a map or array value assignment - assign the property
directly:
+ setProperty(object, propertyPath, value);
+ } else {
+ //we're assigning a map or array entry. Check to see which we
should call:
+ if (isTypedProperty(object, mapPropertyPath, Map.class)) {
+ Map map = (Map)getProperty(object, mapPropertyPath);
+ Object mapKey = resolveValue(keyString);
+ //noinspection unchecked
+ map.put(mapKey, value);
+ } else {
+ //must be an array property. Convert the key string to an
index:
+ int index = Integer.valueOf(keyString);
+ setIndexedProperty(object, mapPropertyPath, index, value);
+ }
+ }
+ } else {
+ //property is being referenced as part of a nested path. Find the
referenced map/array entry and
+ //recursively call this method with the remaining property path
+ Object referencedValue = null;
+ if (isTypedProperty(object, mapPropertyPath, Map.class)) {
+ Map map = (Map)getProperty(object, mapPropertyPath);
+ Object mapKey = resolveValue(keyString);
+ referencedValue = map.get(mapKey);
+ } else {
+ //must be an array property:
+ int index = Integer.valueOf(keyString);
+ referencedValue = getIndexedProperty(object, mapPropertyPath,
index);
+ }
+
+ if (referencedValue == null) {
+ throw new ConfigurationException("Referenced map/array value
'" + mapPropertyPath + "[" +
+ keyString + "]' does not exist.");
+ }
+
+ applyProperty(referencedValue, remaining, value);
+ }
+ }
+
+ private void setProperty(Object object, String propertyPath, Object value)
{
+ try {
+ if (log.isTraceEnabled()) {
+ log.trace("Applying property [{}] value [{}] on object of type
[{}]",
+ new Object[]{propertyPath, value,
object.getClass().getName()});
+ }
+ BeanUtils.setProperty(object, propertyPath, value);
+ } catch (Exception e) {
+ String msg = "Unable to set property '" + propertyPath + "' with
value [" + value + "] on object " +
+ "of type " + (object != null ? object.getClass().getName()
: null) + ". If " +
+ "'" + value + "' is a reference to another (previously
defined) object, prefix it with " +
+ "'" + OBJECT_REFERENCE_BEGIN_TOKEN + "' to indicate that
the referenced " +
+ "object should be used as the actual value. " +
+ "For example, " + OBJECT_REFERENCE_BEGIN_TOKEN + value;
+ throw new ConfigurationException(msg, e);
+ }
+ }
+
+ private Object getProperty(Object object, String propertyPath) {
+ try {
+ return PropertyUtils.getProperty(object, propertyPath);
+ } catch (Exception e) {
+ throw new ConfigurationException("Unable to access property '" +
propertyPath + "'", e);
+ }
+ }
+
+ private void setIndexedProperty(Object object, String propertyPath, int
index, Object value) {
+ try {
+ PropertyUtils.setIndexedProperty(object, propertyPath, index,
value);
+ } catch (Exception e) {
+ throw new ConfigurationException("Unable to set array property '"
+ propertyPath + "'", e);
+ }
+ }
+
+ private Object getIndexedProperty(Object object, String propertyPath, int
index) {
+ try {
+ return PropertyUtils.getIndexedProperty(object, propertyPath,
index);
+ } catch (Exception e) {
+ throw new ConfigurationException("Unable to acquire array property
'" + propertyPath + "'", e);
+ }
+ }
+
+ protected boolean isIndexedPropertyAssignment(String propertyPath) {
+ return propertyPath.endsWith("" + MAP_PROPERTY_END_TOKEN);
+ }
protected void applyProperty(Object object, String propertyName, String
stringValue) {
@@ -370,6 +485,9 @@ public class ReflectionBuilder {
value = null;
} else if (EMPTY_STRING_VALUE_TOKEN.equals(stringValue)) {
value = StringUtils.EMPTY_STRING;
+ } else if (isIndexedPropertyAssignment(propertyName)) {
+ String checked = checkForNullOrEmptyLiteral(stringValue);
+ value = resolveValue(checked);
} else if (isTypedProperty(object, propertyName, Set.class)) {
value = toSet(stringValue);
} else if (isTypedProperty(object, propertyName, Map.class)) {
@@ -387,21 +505,7 @@ public class ReflectionBuilder {
value = resolveValue(checked);
}
- try {
- if (log.isTraceEnabled()) {
- log.trace("Applying property [{}] value [{}] on object of type
[{}]",
- new Object[]{propertyName, value,
object.getClass().getName()});
- }
- BeanUtils.setProperty(object, propertyName, value);
- } catch (Exception e) {
- String msg = "Unable to set property '" + propertyName + "' with
value [" + stringValue + "] on object " +
- "of type " + (object != null ? object.getClass().getName()
: null) + ". If " +
- "'" + stringValue + "' is a reference to another
(previously defined) object, prefix it with " +
- "'" + OBJECT_REFERENCE_BEGIN_TOKEN + "' to indicate that
the referenced " +
- "object should be used as the actual value. " +
- "For example, " + OBJECT_REFERENCE_BEGIN_TOKEN +
stringValue;
- throw new ConfigurationException(msg, e);
- }
+ applyProperty(object, propertyName, value);
}
}
Added:
shiro/trunk/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
URL:
http://svn.apache.org/viewvc/shiro/trunk/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy?rev=1228564&view=auto
==============================================================================
---
shiro/trunk/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
(added)
+++
shiro/trunk/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
Sat Jan 7 03:36:57 2012
@@ -0,0 +1,392 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shiro.config
+
+import org.apache.shiro.codec.Base64
+import org.apache.shiro.codec.CodecSupport
+import org.apache.shiro.codec.Hex
+import org.apache.shiro.util.CollectionUtils
+
+/**
+ * Unit tests for the {@link ReflectionBuilder} implementation.
+ */
+class ReflectionBuilderTest extends GroovyTestCase {
+
+ void testStandardPropertyAssignment() {
+ ReflectionBuilder builder = new ReflectionBuilder();
+
+ CompositeBean cBean = new CompositeBean();
+ builder.applyProperty(cBean, 'stringProp', 'hello world')
+ builder.applyProperty(cBean, 'booleanProp', true)
+ builder.applyProperty(cBean, 'intProp', 42)
+ builder.applyProperty(cBean, 'simpleBean', new SimpleBean())
+
+ assertTrue cBean.stringProp == 'hello world'
+ assertTrue cBean.booleanProp
+ assertTrue cBean.intProp == 42
+ assertTrue cBean.simpleBean instanceof SimpleBean
+ }
+
+ void testMapEntryAssignment() {
+ ReflectionBuilder builder = new ReflectionBuilder();
+
+ CompositeBean cBean = new CompositeBean();
+ cBean.simpleBeanMap = ['simpleBean1': new SimpleBean()]
+
+ builder.applyProperty(cBean, 'simpleBeanMap[simpleBean2]', new
SimpleBean())
+
+ assertTrue cBean.simpleBeanMap['simpleBean2'] instanceof SimpleBean
+ }
+
+ void testArrayEntryAssignment() {
+ ReflectionBuilder builder = new ReflectionBuilder();
+
+ CompositeBean cBean = new CompositeBean();
+ cBean.compositeBeanArray = new CompositeBean[1];
+
+ builder.applyProperty(cBean, 'compositeBeanArray[0]', new
CompositeBean())
+
+ assertTrue cBean.compositeBeanArray[0] instanceof CompositeBean
+ }
+
+ void testNestedPathAssignment() {
+ ReflectionBuilder builder = new ReflectionBuilder();
+
+ CompositeBean cbean1 = new CompositeBean('cbean1');
+ cbean1.compositeBeanMap = ['cbean2': new CompositeBean('cbean2')]
+ cbean1.compositeBeanMap['cbean2'].compositeBeanArray = new
CompositeBean[2];
+
+ builder.applyProperty(cbean1,
"compositeBeanMap[cbean2].compositeBeanArray[0]", new CompositeBean('cbean3'))
+ builder.applyProperty(cbean1,
"compositeBeanMap[cbean2].compositeBeanArray[0].simpleBean", new
SimpleBean('sbean1'))
+
+ assertTrue
cbean1.compositeBeanMap['cbean2'].compositeBeanArray[0].name == 'cbean3'
+ assertTrue
cbean1.compositeBeanMap['cbean2'].compositeBeanArray[0].simpleBean.name ==
'sbean1'
+ }
+
+ //asserts SHIRO-305: https://issues.apache.org/jira/browse/SHIRO-305
+ void testNestedMapAssignmentWithPeriodDelimitedKeys() {
+ def ini = new Ini()
+ ini.load('''
+ ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
+
ldapRealm.contextFactory.environment[java.naming.security.protocol] = ssl
+
ldapRealm.contextFactory.environment[com.sun.jndi.ldap.connect.pool.protocol] =
plain ssl
+
ldapRealm.contextFactory.environment[com.sun.jndi.ldap.connect.pool] = true
+ ''')
+ def builder = new ReflectionBuilder()
+ def objects = builder.buildObjects(ini.getSections().iterator().next())
+
+ assertFalse objects.isEmpty()
+ assertEquals 'ssl',
objects['ldapRealm'].contextFactory.environment['java.naming.security.protocol']
+ }
+
+ void testSimpleConfig() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.stringProp", "blah");
+ defs.put("compositeBean.booleanProp", "true");
+ defs.put("compositeBean.intProp", "42");
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertNotNull(compositeBean);
+ assertEquals(compositeBean.getStringProp(), "blah");
+ assertTrue(compositeBean.isBooleanProp());
+ assertEquals(compositeBean.getIntProp(), 42);
+ }
+
+ void testWithConfiguredNullValue() {
+ Map<String,Object> defaults = new LinkedHashMap<String,Object>();
+ CompositeBean cBean = new CompositeBean();
+ cBean.setSimpleBean(new SimpleBean());
+ defaults.put("compositeBean", cBean);
+
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("compositeBean.intProp", "42");
+ defs.put("compositeBean.booleanProp", "true");
+ defs.put("compositeBean.stringProp", "test");
+ defs.put("compositeBean.simpleBean", "null");
+
+ ReflectionBuilder builder = new ReflectionBuilder(defaults);
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertNotNull(compositeBean);
+ assertTrue(compositeBean.isBooleanProp());
+ assertEquals(compositeBean.getIntProp(), 42);
+ assertEquals("test", compositeBean.getStringProp());
+ assertNull(compositeBean.getSimpleBean());
+ }
+
+ void testWithConfiguredNullLiteralValue() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.intProp", "42");
+ defs.put("compositeBean.booleanProp", "true");
+ defs.put("compositeBean.stringProp", "\"null\"");
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertNotNull(compositeBean);
+ assertTrue(compositeBean.isBooleanProp());
+ assertEquals(compositeBean.getIntProp(), 42);
+ assertEquals("null", compositeBean.getStringProp());
+ }
+
+ void testWithConfiguredEmptyStringValue() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.intProp", "42");
+ defs.put("compositeBean.booleanProp", "true");
+ defs.put("compositeBean.stringProp", "\"\"");
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertNotNull(compositeBean);
+ assertTrue(compositeBean.isBooleanProp());
+ assertEquals(compositeBean.getIntProp(), 42);
+ assertEquals("", compositeBean.getStringProp());
+ }
+
+ void testWithConfiguredEmptyStringLiteralValue() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.intProp", "42");
+ defs.put("compositeBean.booleanProp", "true");
+ defs.put("compositeBean.stringProp", "\"\"\"\"");
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertNotNull(compositeBean);
+ assertTrue(compositeBean.isBooleanProp());
+ assertEquals(compositeBean.getIntProp(), 42);
+ assertEquals("\"\"", compositeBean.getStringProp());
+ }
+
+ void testSimpleConfigWithDollarSignStringValue() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.stringProp", '\\$500');
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertEquals(compositeBean.getStringProp(), '$500');
+ }
+
+ void testObjectReferenceConfig() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean.intProp", "101");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.stringProp", "blah");
+ defs.put("compositeBean.simpleBean", '$simpleBean');
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map beans = builder.buildObjects(defs);
+
+ CompositeBean compositeBean = (CompositeBean)
beans.get("compositeBean");
+ assertNotNull(compositeBean);
+ assertEquals(compositeBean.getStringProp(), "blah");
+ SimpleBean simpleBean = (SimpleBean) beans.get("simpleBean");
+ assertNotNull(simpleBean);
+ assertNotNull(compositeBean.getSimpleBean());
+ assertEquals(simpleBean, compositeBean.getSimpleBean());
+ assertEquals(simpleBean.getIntProp(), 101);
+ }
+
+ void testObjectReferenceConfigWithTypeMismatch() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean", "org.apache.shiro.config.SimpleBean");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBean", "simpleBean");
+ ReflectionBuilder builder = new ReflectionBuilder();
+ try {
+ builder.buildObjects(defs);
+ "Should have encountered an " + ConfigurationException.class.name
+ } catch (ConfigurationException expected) {
+ }
+ }
+
+ void testObjectReferenceConfigWithInvalidReference() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean", "org.apache.shiro.config.SimpleBean");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBean", '$foo');
+ ReflectionBuilder builder = new ReflectionBuilder();
+ try {
+ builder.buildObjects(defs);
+ fail "should have encountered an " +
UnresolveableReferenceException.class.name
+ } catch (UnresolveableReferenceException expected) {
+ }
+ }
+
+ 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());
+ }
+
+ 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());
+ }
+
+ void testCollectionProperty() {
+ 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.simpleBeanCollection", '$simpleBean1,
$simpleBean2, $simpleBean2');
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ CompositeBean cBean = (CompositeBean) objects.get("compositeBean");
+ assertNotNull(cBean);
+ Collection<SimpleBean> simpleBeans = cBean.getSimpleBeanCollection();
+ assertNotNull(simpleBeans);
+ assertTrue(simpleBeans instanceof List);
+ assertEquals(3, simpleBeans.size());
+ }
+
+ void testByteArrayHexProperty() {
+ String source = "Hello, world.";
+ byte[] bytes = CodecSupport.toBytes(source);
+ String hex = Hex.encodeToString(bytes);
+ String hexValue = "0x" + hex;
+
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean.byteArrayProp", hexValue);
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ SimpleBean bean = (SimpleBean) objects.get("simpleBean");
+ assertNotNull(bean);
+ byte[] beanBytes = bean.getByteArrayProp();
+ assertNotNull(beanBytes);
+ String reconstituted = CodecSupport.toString(beanBytes);
+ assertEquals(source, reconstituted);
+ }
+
+ void testByteArrayBase64Property() {
+ String source = "Hello, world.";
+ byte[] bytes = CodecSupport.toBytes(source);
+ String base64 = Base64.encodeToString(bytes);
+
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBean", "org.apache.shiro.config.SimpleBean");
+ defs.put("simpleBean.byteArrayProp", base64);
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ SimpleBean bean = (SimpleBean) objects.get("simpleBean");
+ byte[] beanBytes = bean.getByteArrayProp();
+ assertNotNull(beanBytes);
+ assertTrue(Arrays.equals(beanBytes, bytes));
+ String reconstituted = CodecSupport.toString(beanBytes);
+ assertEquals(reconstituted, source);
+ }
+
+ 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);
+ }
+
+ 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());
+ }
+
+ void testFactoryInstantiation() {
+ Map<String, String> defs = new LinkedHashMap<String, String>();
+ defs.put("simpleBeanFactory",
"org.apache.shiro.config.SimpleBeanFactory");
+ defs.put("simpleBeanFactory.factoryInt", "5");
+ defs.put("simpleBeanFactory.factoryString", "someString");
+ defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+ defs.put("compositeBean.simpleBean", '$simpleBeanFactory');
+
+ ReflectionBuilder builder = new ReflectionBuilder();
+ Map objects = builder.buildObjects(defs);
+ assertFalse(CollectionUtils.isEmpty(objects));
+ CompositeBean compositeBean = (CompositeBean)
objects.get("compositeBean");
+ SimpleBean bean = compositeBean.getSimpleBean();
+ assertNotNull(bean);
+ assertEquals(5, bean.getIntProp());
+ assertEquals("someString", bean.getStringProp());
+ }
+}
Modified:
shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java?rev=1228564&r1=1228563&r2=1228564&view=diff
==============================================================================
--- shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java
(original)
+++ shiro/trunk/core/src/test/java/org/apache/shiro/config/CompositeBean.java
Sat Jan 7 03:36:57 2012
@@ -28,6 +28,8 @@ import java.util.Set;
*/
@SuppressWarnings({"UnusedDeclaration"})
public class CompositeBean {
+
+ private String name;
private String stringProp;
private boolean booleanProp;
@@ -38,9 +40,23 @@ public class CompositeBean {
private List<SimpleBean> simpleBeanList;
private Collection<SimpleBean> simpleBeanCollection;
private Map<String, SimpleBean> simpleBeanMap;
+ private Map<String, CompositeBean> compositeBeanMap;
+ private CompositeBean[] compositeBeanArray;
public CompositeBean() {
}
+
+ public CompositeBean(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
public String getStringProp() {
return stringProp;
@@ -105,4 +121,20 @@ public class CompositeBean {
public void setSimpleBeanMap(Map<String, SimpleBean> simpleBeanMap) {
this.simpleBeanMap = simpleBeanMap;
}
+
+ public Map<String, CompositeBean> getCompositeBeanMap() {
+ return compositeBeanMap;
+ }
+
+ public void setCompositeBeanMap(Map<String, CompositeBean>
compositeBeanMap) {
+ this.compositeBeanMap = compositeBeanMap;
+ }
+
+ public CompositeBean[] getCompositeBeanArray() {
+ return compositeBeanArray;
+ }
+
+ public void setCompositeBeanArray(CompositeBean[] compositeBeanArray) {
+ this.compositeBeanArray = compositeBeanArray;
+ }
}
Modified: shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java?rev=1228564&r1=1228563&r2=1228564&view=diff
==============================================================================
--- shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java
(original)
+++ shiro/trunk/core/src/test/java/org/apache/shiro/config/SimpleBean.java Sat
Jan 7 03:36:57 2012
@@ -24,6 +24,8 @@ import java.util.List;
* @since 1.0
*/
public class SimpleBean {
+
+ private String name;
private String stringProp = null;
private int intProp;
@@ -33,6 +35,18 @@ public class SimpleBean {
public SimpleBean() {
}
+
+ public SimpleBean(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
public String getStringProp() {
return stringProp;