Hiya
Name was a property of the bean, not the beanName itself.
Indeed; as you say, the code to change this to what you want is trivial, to wit...
Code:
package foo;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public final class CustomCollectionFactoryBean implements FactoryBean, InitializingBean {
private List list;
private Map map;
public void setSourceList(final List list) {
this.list = list;
}
public Object getObject() throws Exception {
if (map == null) {
map = new Hashtable(this.list.size());
for (Iterator it = this.list.iterator(); it.hasNext();) {
Nameable named = (Nameable) it.next();
map.put(named.getName(), named);
}
}
return map;
}
public Class getObjectType() {
return Map.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
if (this.list == null) {
throw new IllegalArgumentException("The 'SourceList' property is required.");
}
}
}
Code:
<?xml version="1.0" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="corbaTransport" class="foo.SimpleNameable">
<property name="name" value="Rilo"/>
</bean>
<bean id="otherTransport" class="foo.SimpleNameable">
<property name="name" value="Kiley"/>
</bean>
<bean id="bagOfBeans" class="foo.CustomCollectionFactoryBean">
<property name="sourceList">
<list>
<ref local="corbaTransport"/>
<ref local="otherTransport"/>
</list>
</property>
</bean>
</beans>
Code:
package foo;
public interface Nameable {
public String getName();
public void setName(String name);
}
Code:
package foo;
public final class SimpleNameable implements Nameable {
private String name;
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}
Code:
package foo;
import com.isis.icapfe.modelling.Transport;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import java.util.Map;
import java.util.Iterator;
public final class Main {
@SuppressWarnings("unchecked")
public static void main(final String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("beans.xml");
Map beans = (Map) ctx.getBean("bagOfBeans");
for (Iterator iterator = beans.keySet().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
System.out.println(name + " : " + beans.get(name));
}
}
}
This is the type of corner case for which the FactoryBean abstraction is a fit (I'll agree that it's not nice, but there ain't nothing to the code as you can see).... this is surely better than extending the DTD? A forthcoming release of classic Spring will have extension points in the parser so that you can define your own XML syntax callbacks however you see fit. Maybe that will be a better solution for you.
Ciao
Rick