bringing faces in-line with binding

This commit is contained in:
Keith Donald
2008-06-30 19:47:35 +00:00
parent ad0cee22bb
commit b181862cfb
9 changed files with 86 additions and 91 deletions

View File

@@ -171,45 +171,86 @@ public class GenericConversionService implements ConversionService {
// internal helpers
private Map findConvertersForSource(Class sourceClass) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass);
while (!classQueue.isEmpty()) {
sourceClass = (Class) classQueue.removeLast();
Map sourceTargetConverters = (Map) sourceClassConverters.get(sourceClass);
if (sourceClass.isInterface()) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass);
while (!classQueue.isEmpty()) {
sourceClass = (Class) classQueue.removeLast();
Map sourceTargetConverters = (Map) sourceClassConverters.get(sourceClass);
if (sourceTargetConverters != null && !sourceTargetConverters.isEmpty()) {
return sourceTargetConverters;
}
// queue up source class's implemented interfaces.
Class[] interfaces = sourceClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
}
}
Map sourceTargetConverters = (Map) sourceClassConverters.get(Object.class);
if (sourceTargetConverters != null && !sourceTargetConverters.isEmpty()) {
return sourceTargetConverters;
} else {
return Collections.EMPTY_MAP;
}
if (!sourceClass.isInterface() && sourceClass.getSuperclass() != null) {
classQueue.addFirst(sourceClass.getSuperclass());
}
// queue up source class's implemented interfaces.
Class[] interfaces = sourceClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
} else {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass);
while (!classQueue.isEmpty()) {
sourceClass = (Class) classQueue.removeLast();
Map sourceTargetConverters = (Map) sourceClassConverters.get(sourceClass);
if (sourceTargetConverters != null && !sourceTargetConverters.isEmpty()) {
return sourceTargetConverters;
}
if (sourceClass.getSuperclass() != null) {
classQueue.addFirst(sourceClass.getSuperclass());
}
// queue up source class's implemented interfaces.
Class[] interfaces = sourceClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
}
}
return Collections.EMPTY_MAP;
}
return Collections.EMPTY_MAP;
}
private Converter findTargetConverter(Map sourceTargetConverters, Class targetClass) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
targetClass = (Class) classQueue.removeLast();
Converter converter = (Converter) sourceTargetConverters.get(targetClass);
if (converter != null) {
return converter;
if (targetClass.isInterface()) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
targetClass = (Class) classQueue.removeLast();
Converter converter = (Converter) sourceTargetConverters.get(targetClass);
if (converter != null) {
return converter;
}
// queue up target class's implemented interfaces.
Class[] interfaces = targetClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
}
}
if (!targetClass.isInterface() && targetClass.getSuperclass() != null) {
classQueue.addFirst(targetClass.getSuperclass());
}
// queue up target class's implemented interfaces.
Class[] interfaces = targetClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
return (Converter) sourceTargetConverters.get(Object.class);
} else {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
targetClass = (Class) classQueue.removeLast();
Converter converter = (Converter) sourceTargetConverters.get(targetClass);
if (converter != null) {
return converter;
}
if (targetClass.getSuperclass() != null) {
classQueue.addFirst(targetClass.getSuperclass());
}
// queue up target class's implemented interfaces.
Class[] interfaces = targetClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
}
}
return null;
}
return null;
}
private Class convertToWrapperClassIfNecessary(Class targetType) {

View File

@@ -19,7 +19,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils;
import org.springframework.binding.format.registry.DefaultFormatterRegistry;
import org.springframework.faces.model.converter.FacesConversionService;
import org.springframework.faces.webflow.JsfManagedBeanAwareELExpressionParser;
import org.springframework.faces.webflow.JsfViewFactoryCreator;
@@ -50,10 +49,6 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle
private static final String CONVERSION_SERVICE_PROPERTY = "conversionService";
private static final String FORMATTER_REGISTRY_ATTRIBUTE = "formatter-registry";
private static final String FORMATTER_REGISTRY_PROPERTY = "formatterRegistry";
protected Class getBeanClass(Element element) {
return FlowBuilderServices.class;
}
@@ -66,7 +61,6 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle
} else {
parseExpressionParser(element, definitionBuilder);
}
parseFormatterRegistry(element, definitionBuilder);
parseConversionService(element, definitionBuilder);
parseViewFactoryCreator(element, definitionBuilder);
}
@@ -80,16 +74,6 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle
}
}
private void parseFormatterRegistry(Element element, BeanDefinitionBuilder definitionBuilder) {
String formatterRegistry = element.getAttribute(FORMATTER_REGISTRY_ATTRIBUTE);
if (StringUtils.hasText(formatterRegistry)) {
definitionBuilder.addPropertyReference(FORMATTER_REGISTRY_PROPERTY, formatterRegistry);
} else {
definitionBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, DefaultFormatterRegistry
.getSharedInstance());
}
}
private void parseConversionService(Element element, BeanDefinitionBuilder definitionBuilder) {
String conversionService = element.getAttribute(CONVERSION_SERVICE_ATTRIBUTE);
if (StringUtils.hasText(conversionService)) {

View File

@@ -27,15 +27,6 @@ This tag is only needed when you wish to plugin custom implementations.
<xsd:documentation>
<![CDATA[
The custom ConversionService implementation to use to convert from one type to another.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="formatter-registry">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The custom FormatterRegistry implementation to use to format model properties for display in a View.
]]>
</xsd:documentation>
</xsd:annotation>

View File

@@ -20,7 +20,7 @@ import java.util.List;
import javax.faces.model.DataModel;
import org.springframework.binding.convert.Converter;
import org.springframework.binding.convert.converters.Converter;
import org.springframework.faces.model.OneSelectionTrackingListDataModel;
import org.springframework.util.ClassUtils;
@@ -32,15 +32,15 @@ import org.springframework.util.ClassUtils;
*/
public class DataModelConverter implements Converter {
public Class[] getSourceClasses() {
return new Class[] { Object[].class, List.class, Object.class };
public Class getSourceClass() {
return Object.class;
}
public Class[] getTargetClasses() {
return new Class[] { DataModel.class };
public Class getTargetClass() {
return DataModel.class;
}
public Object convert(Object source, Class targetClass, Object context) throws Exception {
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
if (targetClass.equals(DataModel.class)) {
targetClass = OneSelectionTrackingListDataModel.class;
}

View File

@@ -12,10 +12,7 @@ e.org/licenses/LICENSE-2.0
*/
package org.springframework.faces.model.converter;
import javax.faces.model.DataModel;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.converters.TextToClass;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.faces.model.OneSelectionTrackingListDataModel;
@@ -38,7 +35,5 @@ public class FacesConversionService extends DefaultConversionService {
protected void addFacesConverters() {
addConverter(new DataModelConverter());
TextToClass classConverter = (TextToClass) getConverter(String.class, Class.class);
classConverter.addAlias("dataModel", DataModel.class);
}
}

View File

@@ -17,9 +17,9 @@ package org.springframework.faces.webflow;
import javax.faces.lifecycle.Lifecycle;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.format.FormatterRegistry;
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
import org.springframework.webflow.execution.ViewFactory;
@@ -35,7 +35,7 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
private Lifecycle lifecycle;
public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser,
FormatterRegistry formatterRegistry) {
ConversionService conversionService) {
return new JsfViewFactory(viewIdExpression, getLifecycle());
}

View File

@@ -7,8 +7,6 @@ import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.FormatterRegistry;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.faces.model.converter.FacesConversionService;
import org.springframework.faces.webflow.JSFMockHelper;
@@ -56,13 +54,12 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
assertNotNull(builderServices.getExpressionParser());
assertTrue(builderServices.getViewFactoryCreator() instanceof TestViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
assertTrue(builderServices.getFormatterRegistry() instanceof TestFormatterRegistry);
}
public static class TestViewFactoryCreator implements ViewFactoryCreator {
public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser,
FormatterRegistry formatterRegistry) {
ConversionService conversionService) {
throw new UnsupportedOperationException("Auto-generated method stub");
}
@@ -94,16 +91,4 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
}
}
public static class TestFormatterRegistry implements FormatterRegistry {
public Formatter getFormatter(Class clazz) {
throw new UnsupportedOperationException("Auto-generated method stub");
}
public Formatter getFormatter(Class clazz, String id) {
throw new UnsupportedOperationException("Auto-generated method stub");
}
}
}

View File

@@ -15,8 +15,7 @@
<faces:flow-builder-services id="flowBuilderServicesCustom"
expression-parser="customExpressionParser"
view-factory-creator="customViewFactoryCreator"
conversion-service="customConversionService"
formatter-registry="customFormatterRegistry"/>
conversion-service="customConversionService"/>
<bean id="customExpressionParser" class="org.springframework.webflow.expression.DefaultExpressionParserFactory" factory-method="getExpressionParser"/>
@@ -24,6 +23,4 @@
<bean id="customConversionService" class="org.springframework.faces.config.FacesFlowBuilderServicesBeanDefinitionParserTests$TestConversionService"/>
<bean id="customFormatterRegistry" class="org.springframework.faces.config.FacesFlowBuilderServicesBeanDefinitionParserTests$TestFormatterRegistry"/>
</beans>

View File

@@ -9,7 +9,7 @@ import javax.faces.model.ListDataModel;
import junit.framework.TestCase;
import org.springframework.binding.convert.Converter;
import org.springframework.binding.convert.converters.Converter;
import org.springframework.faces.model.SerializableListDataModel;
public class DataModelConverterTests extends TestCase {
@@ -19,7 +19,7 @@ public class DataModelConverterTests extends TestCase {
public void testConvertListToDataModel() throws Exception {
List sourceList = new ArrayList();
DataModel resultModel = (DataModel) converter.convert(sourceList, DataModel.class, null);
DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList, DataModel.class);
assertNotNull(resultModel);
assertSame(sourceList, resultModel.getWrappedData());
@@ -28,7 +28,7 @@ public class DataModelConverterTests extends TestCase {
public void testConvertListToListDataModel() throws Exception {
List sourceList = new ArrayList();
DataModel resultModel = (DataModel) converter.convert(sourceList, ListDataModel.class, null);
DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList, ListDataModel.class);
assertNotNull(resultModel);
assertSame(sourceList, resultModel.getWrappedData());
@@ -37,7 +37,8 @@ public class DataModelConverterTests extends TestCase {
public void testConvertListToSerializableListDataModel() throws Exception {
List sourceList = new ArrayList();
DataModel resultModel = (DataModel) converter.convert(sourceList, SerializableListDataModel.class, null);
DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList,
SerializableListDataModel.class);
assertNotNull(resultModel);
assertSame(sourceList, resultModel.getWrappedData());
@@ -47,7 +48,8 @@ public class DataModelConverterTests extends TestCase {
public void testConvertListToSerializableListDataModelNullSource() throws Exception {
List sourceList = null;
DataModel resultModel = (DataModel) converter.convert(sourceList, SerializableListDataModel.class, null);
DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList,
SerializableListDataModel.class);
assertNotNull(resultModel);
assertTrue(resultModel instanceof Serializable);