Revision: 1225
Author:   mathiasbr
Date:     2006-07-17 03:02:15 -0700 (Mon, 17 Jul 2006)
ViewCVS:  http://svn.sourceforge.net/spring-rich-c/?rev=1225&view=rev

Log Message:
-----------
1st. Part for RCP-357 which refactors constraint message translation including:

MessageTranslator can now be created through a factory which can be configured 
as a spring bean.
Use of ObjectNameResolver to translate property or field names into a human 
readable form (like displayName in a form)

Modified Paths:
--------------
    
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/RulesValidator.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslator.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/PropertyResults.java
    
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/test/SpringRichTestCase.java
    
trunk/spring-richclient/support/src/test/java/org/springframework/rules/ValidationResultsTests.java
    
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/messages.properties
    
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/rules-context.xml

Added Paths:
-----------
    
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslatorFactory.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslator.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslatorFactory.java
    
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/ObjectNameResolver.java

Removed Paths:
-------------
    
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/FormModelAwareMessageTranslator.java
Deleted: 
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/FormModelAwareMessageTranslator.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/FormModelAwareMessageTranslator.java
   2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/FormModelAwareMessageTranslator.java
   2006-07-17 10:02:15 UTC (rev 1225)
@@ -1,227 +0,0 @@
-/*
- * Copyright 2002-2005 the original author or authors.
- * 
- * Licensed 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.springframework.binding.validation.support;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.binding.form.FormModel;
-import org.springframework.context.MessageSource;
-import org.springframework.context.MessageSourceResolvable;
-import org.springframework.context.support.DefaultMessageSourceResolvable;
-import org.springframework.core.ReflectiveVisitorHelper;
-import org.springframework.core.closure.Constraint;
-import org.springframework.core.style.StylerUtils;
-import org.springframework.rules.constraint.And;
-import org.springframework.rules.constraint.ClosureResultConstraint;
-import org.springframework.rules.constraint.Not;
-import org.springframework.rules.constraint.Or;
-import org.springframework.rules.constraint.ParameterizedBinaryConstraint;
-import org.springframework.rules.constraint.Range;
-import org.springframework.rules.constraint.StringLengthConstraint;
-import 
org.springframework.rules.constraint.property.CompoundPropertyConstraint;
-import 
org.springframework.rules.constraint.property.ParameterizedPropertyConstraint;
-import org.springframework.rules.constraint.property.PropertiesConstraint;
-import org.springframework.rules.constraint.property.PropertyValueConstraint;
-import org.springframework.rules.reporting.DefaultMessageTranslator;
-import org.springframework.rules.reporting.PropertyResults;
-import org.springframework.rules.reporting.TypeResolvable;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * A validation message translator that is aware of form property names info 
exposed through
- * the FieldFace class.
- * 
- * TODO: This class is an almost exact copy of DefaultMessageTranslator 
ideally we
- * would just be able to extend that class but I can't modify 
DefaultMessageTranslator
- * as it's part of Spring. OH. 
- */
-public class FormModelAwareMessageTranslator {
-
-    protected static final Log logger = 
LogFactory.getLog(DefaultMessageTranslator.class);
-
-    private final ReflectiveVisitorHelper visitorSupport = new 
ReflectiveVisitorHelper();
-
-    private boolean appendValue = false;
-
-    PropertyResults results;
-
-    private final List args = new ArrayList();
-
-    private MessageSource messages;
-
-    private final FormModel formModel;
-
-    public FormModelAwareMessageTranslator(FormModel formModel, MessageSource 
messages) {
-        setMessageSource(messages);
-        this.formModel = formModel;
-    }
-
-    public void setMessageSource(MessageSource messageSource) {
-        Assert.notNull(messageSource, "messageSource is required");
-        this.messages = messageSource;
-    }
-
-    public String getMessage(PropertyResults results) {
-        Assert.notNull(results, "No property results specified");
-        args.clear();
-        return buildMessage(results.getPropertyName(), 
results.getRejectedValue(), results.getViolatedConstraint(),
-                Locale.getDefault());
-    }
-
-    private String buildMessage(String propertyName, Object rejectedValue, 
Constraint constraint, Locale locale) {
-        StringBuffer buf = new StringBuffer(255);
-        MessageSourceResolvable[] args = resolveArguments(constraint);
-        if (logger.isDebugEnabled()) {
-            logger.debug(StylerUtils.style(args));
-        }
-        if (propertyName != null) {
-            buf.append(getDisplayName(propertyName));
-            buf.append(' ');
-            if (appendValue) {
-                if (rejectedValue != null) {
-                    buf.append("'" + rejectedValue + "'");
-                    buf.append(' ');
-                }
-            }
-        }
-        for (int i = 0; i < args.length - 1; i++) {
-            MessageSourceResolvable arg = args[i];
-            buf.append(messages.getMessage(arg, locale));
-            buf.append(' ');
-        }
-        buf.append(messages.getMessage(args[args.length - 1], locale));
-        buf.append(".");
-        return buf.toString();
-    }
-
-    private String getDisplayName(String propertyName) {
-        return formModel.getFieldFace(propertyName).getDisplayName();
-    }
-
-    private MessageSourceResolvable[] resolveArguments(Constraint constraint) {
-        visitorSupport.invokeVisit(this, constraint);
-        return (MessageSourceResolvable[])args.toArray(new 
MessageSourceResolvable[0]);
-    }
-
-    void visit(CompoundPropertyConstraint rule) {
-        visitorSupport.invokeVisit(this, rule.getPredicate());
-    }
-
-    void visit(PropertiesConstraint e) {
-        add(getMessageCode(e.getConstraint()), new Object[] 
{getDisplayName(e.getOtherPropertyName())},
-                e.toString());
-    }
-
-    void visit(ParameterizedPropertyConstraint e) {
-        add(getMessageCode(e.getConstraint()), new Object[] 
{e.getParameter()}, e.toString());
-    }
-
-    private void add(String code, Object[] args, String defaultMessage) {
-        MessageSourceResolvable resolvable = new 
DefaultMessageSourceResolvable(new String[] {code}, args,
-                defaultMessage);
-        if (logger.isDebugEnabled()) {
-            logger.debug("Adding resolvable: " + resolvable);
-        }
-        this.args.add(resolvable);
-    }
-
-    void visit(PropertyValueConstraint valueConstraint) {
-        visitorSupport.invokeVisit(this, valueConstraint.getConstraint());
-    }
-
-    void visit(And and) {
-        Iterator it = and.iterator();
-        while (it.hasNext()) {
-            Constraint p = (Constraint)it.next();
-            visitorSupport.invokeVisit(this, p);
-            if (it.hasNext()) {
-                add("and", null, "add");
-            }
-        }
-    }
-
-    void visit(Or or) {
-        Iterator it = or.iterator();
-        while (it.hasNext()) {
-            Constraint p = (Constraint)it.next();
-            visitorSupport.invokeVisit(this, p);
-            if (it.hasNext()) {
-                add("or", null, "or");
-            }
-        }
-    }
-
-    void visit(Not not) {
-        add("not", null, "not");
-        visitorSupport.invokeVisit(this, not.getConstraint());
-    }
-
-    //@TODO - consider standard visitor here...
-    void visit(StringLengthConstraint constraint) {
-        ClosureResultConstraint c = 
(ClosureResultConstraint)constraint.getPredicate();
-        Object p = c.getPredicate();
-        MessageSourceResolvable resolvable;
-        if (p instanceof ParameterizedBinaryConstraint) {
-            resolvable = 
handleParameterizedBinaryPredicate((ParameterizedBinaryConstraint)p);
-        }
-        else {
-            resolvable = handleRange((Range)p);
-        }
-        Object[] args = new Object[] {resolvable};
-        add(getMessageCode(constraint), args, constraint.toString());
-    }
-
-    void visit(ClosureResultConstraint c) {
-        visitorSupport.invokeVisit(this, c.getPredicate());
-    }
-
-    private MessageSourceResolvable 
handleParameterizedBinaryPredicate(ParameterizedBinaryConstraint p) {
-        MessageSourceResolvable resolvable = new 
DefaultMessageSourceResolvable(
-                new String[] {getMessageCode(p.getConstraint())}, new Object[] 
{p.getParameter()}, p.toString());
-        return resolvable;
-    }
-
-    private MessageSourceResolvable handleRange(Range r) {
-        MessageSourceResolvable resolvable = new 
DefaultMessageSourceResolvable(new String[] {getMessageCode(r)},
-                new Object[] {r.getMin(), r.getMax()}, r.toString());
-        return resolvable;
-    }
-
-    void visit(Constraint constraint) {
-        if (constraint instanceof Range) {
-            this.args.add(handleRange((Range)constraint));
-        }
-        else {
-            add(getMessageCode(constraint), null, constraint.toString());
-        }
-    }
-
-    private String getMessageCode(Object o) {
-        if (o instanceof TypeResolvable) {
-            String type = ((TypeResolvable)o).getType();
-            if (type != null) {
-                return type;
-            }
-        }
-        return ClassUtils.getShortNameAsProperty(o.getClass());
-    }
-}
\ No newline at end of file

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/RulesValidator.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/RulesValidator.java
    2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/binding/validation/support/RulesValidator.java
    2006-07-17 10:02:15 UTC (rev 1225)
@@ -29,22 +29,24 @@
 import org.springframework.binding.validation.Severity;
 import org.springframework.binding.validation.ValidationMessage;
 import org.springframework.binding.validation.ValidationResults;
-import org.springframework.context.MessageSource;
 import org.springframework.richclient.application.ApplicationServicesLocator;
 import org.springframework.rules.PropertyConstraintProvider;
 import org.springframework.rules.Rules;
 import org.springframework.rules.RulesSource;
 import org.springframework.rules.constraint.property.PropertyConstraint;
 import org.springframework.rules.reporting.BeanValidationResultsCollector;
+import org.springframework.rules.reporting.MessageTranslator;
+import org.springframework.rules.reporting.MessageTranslatorFactory;
+import org.springframework.rules.reporting.ObjectNameResolver;
 import org.springframework.rules.reporting.PropertyResults;
 
-public class RulesValidator implements RichValidator {
+public class RulesValidator implements RichValidator, ObjectNameResolver {
 
     private static final Log logger = LogFactory.getLog(RulesValidator.class);
 
     private final DefaultValidationResults results = new 
DefaultValidationResults();
 
-    private final FormModelAwareMessageTranslator messageTranslator;
+    private final MessageTranslator messageTranslator;
 
     private final Map validationErrors = new HashMap();
 
@@ -74,8 +76,8 @@
         this.formModel = formModel;
         this.rulesSource = rulesSource;
         validationResultsCollector = new BeanValidationResultsCollector(new 
FormModelPropertyAccessStrategy(formModel));
-        MessageSource messageSource = 
(MessageSource)ApplicationServicesLocator.services().getService(MessageSource.class);
-        messageTranslator = new FormModelAwareMessageTranslator(formModel, 
messageSource);
+        MessageTranslatorFactory factory = (MessageTranslatorFactory) 
ApplicationServicesLocator.services().getService(MessageTranslatorFactory.class);
+        messageTranslator = factory.createTranslator(this);
     }
     
     public ValidationResults validate(Object object) {
@@ -184,4 +186,8 @@
     public void setRulesContextId(String rulesContextId) {
         this.rulesContextId = rulesContextId;
     }
+
+       public String resolveObjectName(String objectName) {
+               return formModel.getFieldFace(objectName).getDisplayName();
+       }
 }

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
    2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/application/support/DefaultApplicationServices.java
    2006-07-17 10:02:15 UTC (rev 1225)
@@ -60,6 +60,8 @@
 import 
org.springframework.richclient.security.support.DefaultSecurityControllerManager;
 import org.springframework.richclient.util.Assert;
 import org.springframework.rules.RulesSource;
+import org.springframework.rules.reporting.DefaultMessageTranslatorFactory;
+import org.springframework.rules.reporting.MessageTranslatorFactory;
 import org.springframework.rules.support.DefaultRulesSource;
 
 /**
@@ -537,6 +539,15 @@
     }
 
     /**
+     * Set the message translator registry service implementation
+     * 
+     * @param messageTranslatorFactory
+     */
+    public void setMessageTranslatorFactory( MessageTranslatorFactory 
messageTranslatorFactory ) {
+        services.put(MessageTranslatorFactory.class, messageTranslatorFactory);
+    }
+
+    /**
      * Set the view descriptor registry service implementation bean id
      * 
      * @param viewDescriptorRegistryId bean id
@@ -706,6 +717,16 @@
         }
     };
 
+    protected static final ImplBuilder messageTranslatorFactoryImplBuilder = 
new ImplBuilder() {
+        public Object build( DefaultApplicationServices applicationServices ) {
+            logger.info("Creating default service impl: 
MessageTranslatorFactory");
+            DefaultMessageTranslatorFactory impl = new 
DefaultMessageTranslatorFactory();
+            impl.setMessageSource(applicationServices.getApplicationContext());
+                       return impl;
+        }
+    };
+    
+    
     protected static final ImplBuilder labeledEnumResolverImplBuilder = new 
ImplBuilder() {
         public Object build( DefaultApplicationServices applicationServices ) {
             logger.info("Creating default service impl: LabeledEnumResolver");
@@ -752,5 +773,6 @@
         serviceImplBuilders.put(SecurityControllerManager.class, 
SecurityControllerManagerImplBuilder);
         serviceImplBuilders.put(ValueChangeDetector.class, 
valueChangeDetectorImplBuilder);
         serviceImplBuilders.put(ViewDescriptorRegistry.class, 
viewDescriptorRegistryImplBuilder);
+        serviceImplBuilders.put(MessageTranslatorFactory.class, 
messageTranslatorFactoryImplBuilder);
     }
 }

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslator.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslator.java
     2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslator.java
     2006-07-17 10:02:15 UTC (rev 1225)
@@ -46,7 +46,8 @@
 /**
  * @author Keith Donald
  */
-public class DefaultMessageTranslator {
+public class DefaultMessageTranslator implements MessageTranslator,
+               ObjectNameResolver {
 
        protected static final Log logger = LogFactory
                        .getLog(DefaultMessageTranslator.class);
@@ -55,14 +56,27 @@
 
        private boolean appendValue = false;
 
-       PropertyResults results;
-
        private List args = new ArrayList();
 
        private MessageSource messages;
 
+       private ObjectNameResolver objectNameResolver;
+
+       private Locale locale;
+
        public DefaultMessageTranslator(MessageSource messages) {
+               this(messages, null);
+       }
+
+       public DefaultMessageTranslator(MessageSource messages, 
ObjectNameResolver objectNameResolver) {
+               this(messages, objectNameResolver, null);
+       }
+
+       public DefaultMessageTranslator(MessageSource messages,
+                       ObjectNameResolver objectNameResolver, Locale locale) {
                setMessageSource(messages);
+               this.objectNameResolver = objectNameResolver;
+               this.locale = locale;
        }
 
        public void setMessageSource(MessageSource messageSource) {
@@ -70,47 +84,49 @@
                this.messages = messageSource;
        }
 
+       /*
+        * (non-Javadoc)
+        * 
+        * @see 
org.springframework.rules.reporting.MessageTranslator#getMessage(org.springframework.core.closure.Constraint)
+        */
        public String getMessage(Constraint constraint) {
                String objectName = null;
                if (constraint instanceof PropertyConstraint) {
                        objectName = ((PropertyConstraint) 
constraint).getPropertyName();
                }
-               String message = buildMessage(objectName, null, constraint, 
Locale.getDefault());
+               String message = buildMessage(objectName, null, constraint);
                return message;
        }
 
        public String getMessage(String objectName, Constraint constraint) {
-               return buildMessage(objectName, null, constraint, 
Locale.getDefault());
+               return buildMessage(objectName, null, constraint);
        }
 
        public String getMessage(String objectName, Object rejectedValue,
                        Constraint constraint) {
-               return buildMessage(objectName, rejectedValue, constraint, 
Locale
-                               .getDefault());
+               return buildMessage(objectName, rejectedValue, constraint);
        }
 
        public String getMessage(String objectName, ValidationResults results) {
                return buildMessage(objectName, results.getRejectedValue(), 
results
-                               .getViolatedConstraint(), Locale.getDefault());
+                               .getViolatedConstraint());
        }
 
        public String getMessage(PropertyResults results) {
                Assert.notNull(results, "No property results specified");
                return buildMessage(results.getPropertyName(), results
-                               .getRejectedValue(), 
results.getViolatedConstraint(), Locale
-                               .getDefault());
+                               .getRejectedValue(), 
results.getViolatedConstraint());
        }
 
        private String buildMessage(String objectName, Object rejectedValue,
-                       Constraint constraint, Locale locale) {
+                       Constraint constraint) {
                StringBuffer buf = new StringBuffer(255);
                MessageSourceResolvable[] args = resolveArguments(constraint);
                if (logger.isDebugEnabled()) {
                        logger.debug(StylerUtils.style(args));
                }
                if (objectName != null) {
-                       
buf.append(messages.getMessage(resolvableObjectName(objectName),
-                                       locale));
+                       buf.append(resolveObjectName(objectName));
                        buf.append(' ');
                        if (appendValue) {
                                if (rejectedValue != null) {
@@ -130,6 +146,7 @@
        }
 
        private MessageSourceResolvable[] resolveArguments(Constraint 
constraint) {
+               args.clear();
                visitorSupport.invokeVisit(this, constraint);
                return (MessageSourceResolvable[]) args
                                .toArray(new MessageSourceResolvable[0]);
@@ -142,28 +159,30 @@
        void visit(PropertiesConstraint e) {
                add(
                                getMessageCode(e.getConstraint()),
-                               new 
Object[]{resolvableObjectName(e.getOtherPropertyName())},
+                               new Object[] { 
resolveObjectName(e.getOtherPropertyName()) },
                                e.toString());
        }
 
        void visit(ParameterizedPropertyConstraint e) {
                add(getMessageCode(e.getConstraint()),
-                               new Object[]{e.getParameter()}, e.toString());
+                               new Object[] { e.getParameter() }, 
e.toString());
        }
 
-       private void add(String code, Object[] args, String defaultMessage) {
+       public void add(String code, Object[] args, String defaultMessage) {
                MessageSourceResolvable resolvable = new 
DefaultMessageSourceResolvable(
-                               new String[]{code}, args, defaultMessage);
+                               new String[] { code }, args, defaultMessage);
                if (logger.isDebugEnabled()) {
                        logger.debug("Adding resolvable: " + resolvable);
                }
                this.args.add(resolvable);
        }
 
-       private MessageSourceResolvable resolvableObjectName(String objectName) 
{
-               return new DefaultMessageSourceResolvable(new 
String[]{objectName},
-                               null, new DefaultBeanPropertyNameRenderer()
-                               .renderShortName(objectName));
+       public String resolveObjectName(String objectName) {
+               if(objectNameResolver != null)
+                       return objectNameResolver.resolveObjectName(objectName);
+               return messages.getMessage(objectName, null,
+                               new DefaultBeanPropertyNameRenderer()
+                                               .renderShortName(objectName), 
locale);
        }
 
        void visit(PropertyValueConstraint valueConstraint) {
@@ -197,7 +216,7 @@
                visitorSupport.invokeVisit(this, not.getConstraint());
        }
 
-       //@TODO - consider standard visitor here...
+       // @TODO - consider standard visitor here...
        void visit(StringLengthConstraint constraint) {
                ClosureResultConstraint c = (ClosureResultConstraint) constraint
                                .getPredicate();
@@ -205,11 +224,10 @@
                MessageSourceResolvable resolvable;
                if (p instanceof ParameterizedBinaryConstraint) {
                        resolvable = 
handleParameterizedBinaryPredicate((ParameterizedBinaryConstraint) p);
-               }
-               else {
+               } else {
                        resolvable = handleRange((Range) p);
                }
-               Object[] args = new Object[]{resolvable};
+               Object[] args = new Object[] { resolvable };
                add(getMessageCode(constraint), args, constraint.toString());
        }
 
@@ -220,23 +238,22 @@
        private MessageSourceResolvable handleParameterizedBinaryPredicate(
                        ParameterizedBinaryConstraint p) {
                MessageSourceResolvable resolvable = new 
DefaultMessageSourceResolvable(
-                               new String[]{getMessageCode(p.getConstraint())},
-                               new Object[]{p.getParameter()}, p.toString());
+                               new String[] { 
getMessageCode(p.getConstraint()) },
+                               new Object[] { p.getParameter() }, 
p.toString());
                return resolvable;
        }
 
        private MessageSourceResolvable handleRange(Range r) {
                MessageSourceResolvable resolvable = new 
DefaultMessageSourceResolvable(
-                               new String[]{getMessageCode(r)}, new 
Object[]{r.getMin(),
-                                                                               
                                                                                
                                                        r.getMax()}, 
r.toString());
+                               new String[] { getMessageCode(r) }, new 
Object[] { r.getMin(),
+                                               r.getMax() }, r.toString());
                return resolvable;
        }
 
        void visit(Constraint constraint) {
                if (constraint instanceof Range) {
                        this.args.add(handleRange((Range) constraint));
-               }
-               else {
+               } else {
                        add(getMessageCode(constraint), null, 
constraint.toString());
                }
        }
@@ -250,5 +267,4 @@
                }
                return ClassUtils.getShortNameAsProperty(o.getClass());
        }
-
-}
\ No newline at end of file
+}

Added: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslatorFactory.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslatorFactory.java
                              (rev 0)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslatorFactory.java
      2006-07-17 10:02:15 UTC (rev 1225)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed 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.springframework.rules.reporting;
+
+import java.util.Locale;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.MessageSource;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.util.Assert;
+
+/**
+ * @author Mathias Broekelmann
+ * 
+ */
+public class DefaultMessageTranslatorFactory implements
+               MessageTranslatorFactory, MessageSourceAware, InitializingBean {
+
+       private MessageSource messageSource;
+
+       public MessageTranslator createTranslator(ObjectNameResolver resolver) {
+               return createTranslator(resolver, Locale.getDefault());
+       }
+
+       public MessageTranslator createTranslator(ObjectNameResolver resolver,
+                       Locale locale) {
+               return new DefaultMessageTranslator(messageSource, resolver, 
locale);
+       }
+
+       public void setMessageSource(MessageSource messageSource) {
+               this.messageSource = messageSource;
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               Assert.notNull(messageSource, "messageSource has not been set");
+       }
+}


Property changes on: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/DefaultMessageTranslatorFactory.java
___________________________________________________________________
Name: svn:keywords
   + URL Author Revision Date
Name: svn:eol-style
   + native

Added: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslator.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslator.java
                            (rev 0)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslator.java
    2006-07-17 10:02:15 UTC (rev 1225)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed 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.springframework.rules.reporting;
+
+import org.springframework.core.closure.Constraint;
+
+/**
+ * A message transloator which translates validation results into a human
+ * readable form
+ * 
+ * @author Mathias Broekelmann
+ * 
+ */
+public interface MessageTranslator {
+
+       String getMessage(Constraint constraint);
+
+       String getMessage(String objectName, Constraint constraint);
+
+       String getMessage(String objectName, Object rejectedValue,
+                       Constraint constraint);
+
+       String getMessage(String objectName, ValidationResults results);
+
+       String getMessage(PropertyResults results);
+
+}


Property changes on: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslator.java
___________________________________________________________________
Name: svn:keywords
   + URL Author Revision Date
Name: svn:eol-style
   + native

Added: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslatorFactory.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslatorFactory.java
                             (rev 0)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslatorFactory.java
     2006-07-17 10:02:15 UTC (rev 1225)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed 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.springframework.rules.reporting;
+
+import java.util.Locale;
+
+/**
+ * A factory which creates instances of MessageTranslator
+ * 
+ * @author Mathias Broekelmann
+ * 
+ */
+public interface MessageTranslatorFactory {
+
+       /**
+        * Creates a message translator by using the given object name resolver 
and
+        * the default locale
+        * 
+        * @param resolver
+        *            the object name resolver which is used to resolve a name 
to
+        *            use in the translated message for an object name
+        * @return the created message translator instance, must not be null
+        */
+       MessageTranslator createTranslator(ObjectNameResolver resolver);
+
+       /**
+        * Creates a message translator by using the given object name resolver 
and
+        * the locale
+        * 
+        * @param resolver
+        *            the object name resolver which is used to resolve a name 
to
+        *            use in the translated message for an object name
+        * @param locale
+        *            the locale for the translated messages, if null the 
default
+        *            locale is used
+        * @return the created message translator instance, must not be null
+        */
+       MessageTranslator createTranslator(ObjectNameResolver resolver,
+                       Locale locale);
+}


Property changes on: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/MessageTranslatorFactory.java
___________________________________________________________________
Name: svn:keywords
   + URL Author Revision Date
Name: svn:eol-style
   + native

Added: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/ObjectNameResolver.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/ObjectNameResolver.java
                           (rev 0)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/ObjectNameResolver.java
   2006-07-17 10:02:15 UTC (rev 1225)
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed 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.springframework.rules.reporting;
+
+
+/**
+ * Implementations of this interface are capable to resolve a given field name
+ * to a user friendly display name
+ * 
+ * @author Mathias Broekelmann
+ * 
+ */
+public interface ObjectNameResolver {
+       
+       /** 
+        * resolves a field name to a user friendly display name
+        */
+       String resolveObjectName(String objectName);
+}


Property changes on: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/ObjectNameResolver.java
___________________________________________________________________
Name: svn:keywords
   + URL Author Revision Date
Name: svn:eol-style
   + native

Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/PropertyResults.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/PropertyResults.java
      2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/rules/reporting/PropertyResults.java
      2006-07-17 10:02:15 UTC (rev 1225)
@@ -20,6 +20,7 @@
 import org.springframework.binding.validation.Severity;
 import org.springframework.context.MessageSource;
 import org.springframework.core.closure.Constraint;
+import org.springframework.richclient.application.ApplicationServicesLocator;
 
 /**
  * @author Keith Donald
@@ -30,18 +31,29 @@
     private Object rejectedValue;
     private Constraint violatedConstraint;
     private Severity severity = Severity.ERROR;
+    private MessageTranslatorFactory messageTranslatorFactory;
 
     public PropertyResults(String propertyName, Object rejectedValue,
             Constraint violatedConstraint) {
         this.propertyName = propertyName;
         this.rejectedValue = rejectedValue;
         this.violatedConstraint = violatedConstraint;
+        this.messageTranslatorFactory = (MessageTranslatorFactory) 
ApplicationServicesLocator.services().getService(MessageTranslatorFactory.class);
     }
 
+    /**
+     * @deprecated MessageSource is configured by MessageTranslator. use 
<code>buildMessage(Locale)</code>
+     * @see #buildMessage(Locale)
+     */
     public String buildMessage(MessageSource messages, Locale locale) {
-        return new DefaultMessageTranslator(messages).getMessage(this);
+               return buildMessage(locale);
     }
 
+    public String buildMessage(Locale locale) {
+       MessageTranslator messageTranslator = 
messageTranslatorFactory.createTranslator(null, locale);          
+        return messageTranslator.getMessage(this);
+    }
+
     public String getPropertyName() {
         return propertyName;
     }
@@ -61,5 +73,5 @@
     public Severity getSeverity() {
         return severity;
     }
-    
-}
\ No newline at end of file
+
+}

Modified: 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/test/SpringRichTestCase.java
===================================================================
--- 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/test/SpringRichTestCase.java
   2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/test/SpringRichTestCase.java
   2006-07-17 10:02:15 UTC (rev 1225)
@@ -19,12 +19,13 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.support.StaticApplicationContext;
 import org.springframework.context.support.StaticMessageSource;
 import org.springframework.richclient.application.Application;
 import org.springframework.richclient.application.ApplicationServicesLocator;
+import 
org.springframework.richclient.application.config.ApplicationLifecycleAdvisor;
 import 
org.springframework.richclient.application.config.DefaultApplicationLifecycleAdvisor;
-import 
org.springframework.richclient.application.config.ApplicationLifecycleAdvisor;
 import 
org.springframework.richclient.application.support.DefaultApplicationServices;
 
 /**
@@ -46,14 +47,14 @@
     protected final void setUp() throws Exception {
         try {
             Application.load(null);
-            applicationServices = new DefaultApplicationServices();
+            ConfigurableApplicationContext applicationContext = 
createApplicationContext();
+            applicationServices = new 
DefaultApplicationServices(applicationContext);
             new ApplicationServicesLocator(applicationServices);
 
             final ApplicationLifecycleAdvisor advisor = 
createApplicationLifecycleAdvisor();
             final Application application = new Application(advisor);
             advisor.setApplication(application);
             
-            StaticApplicationContext applicationContext = new 
StaticApplicationContext();
             Application.instance().setApplicationContext(applicationContext);
             applicationServices.setApplicationContext(applicationContext);
 
@@ -68,6 +69,16 @@
         }
     }
 
+       /**
+     * returns the application context to use for testing
+     * 
+     * overwrite to specify a different application context
+     * 
+     * @return this implementation returns an instance of 
StaticApplicationContext
+     */
+    protected ConfigurableApplicationContext createApplicationContext() {
+        return new StaticApplicationContext();
+    }
 
     /**
      * Subclasses may override this to return a custom

Modified: 
trunk/spring-richclient/support/src/test/java/org/springframework/rules/ValidationResultsTests.java
===================================================================
--- 
trunk/spring-richclient/support/src/test/java/org/springframework/rules/ValidationResultsTests.java
 2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/test/java/org/springframework/rules/ValidationResultsTests.java
 2006-07-17 10:02:15 UTC (rev 1225)
@@ -6,10 +6,14 @@
 
 import java.util.Locale;
 
-import junit.framework.TestCase;
-
+import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 import org.springframework.core.closure.Constraint;
+import org.springframework.richclient.application.Application;
+import org.springframework.richclient.application.ApplicationServicesLocator;
+import 
org.springframework.richclient.application.config.DefaultApplicationLifecycleAdvisor;
+import 
org.springframework.richclient.application.support.DefaultApplicationServices;
+import org.springframework.richclient.test.SpringRichTestCase;
 import org.springframework.rules.constraint.CompoundConstraint;
 import 
org.springframework.rules.constraint.property.CompoundPropertyConstraint;
 import org.springframework.rules.factory.Constraints;
@@ -19,20 +23,26 @@
 /**
  * @author Keith Donald
  */
-public class ValidationResultsTests extends TestCase {
+public class ValidationResultsTests extends SpringRichTestCase {
 
-       static ClassPathXmlApplicationContext ac;
        static RulesSource rulesSource;
        static Rules rules;
 
        private static final Constraints constraints = Constraints.instance();
-
-       public void setUp() {
-               ac = new 
ClassPathXmlApplicationContext("org/springframework/rules/rules-context.xml");
-               rulesSource = (RulesSource) ac.getBean("rulesSource");
+       
+       protected void registerAdditionalServices(DefaultApplicationServices 
applicationServices) {
+               applicationServices.setRulesSourceId("rulesSource");
+       }
+       
+       protected void doSetUp() throws Exception {
+               rulesSource = (RulesSource) 
applicationServices.getService(RulesSource.class);
                rules = rulesSource.getRules(Person.class);
        }
 
+       protected ConfigurableApplicationContext createApplicationContext() {
+               return new 
ClassPathXmlApplicationContext("org/springframework/rules/rules-context.xml");
+       }
+
        public void testValidationResultsCollector() {
                Person p = new Person();
                BeanValidationResultsCollector c = new 
BeanValidationResultsCollector(p);
@@ -69,7 +79,7 @@
                BeanValidationResults r = c.collectResults(rules);
                assertEquals(3, r.getViolatedCount());
                String message =
-                               r.getResults("firstName").buildMessage(ac, 
Locale.getDefault());
+                               
r.getResults("firstName").buildMessage(Locale.getDefault());
                System.out.println(message);
                assertEquals(
                                "First Name must have text and must be at least 
2 characters or must *not* equal Last Name.",

Modified: 
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/messages.properties
===================================================================
--- 
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/messages.properties
    2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/messages.properties
    2006-07-17 10:02:15 UTC (rev 1225)
@@ -16,3 +16,7 @@
 args={0} {1} {2} {3} {4}
 validFileChecker=does not exist
 
+firstName.displayName=First Name
+lastName.displayName=Last Name
+requiredIfTrue=must have text if
+propertyPresent={0} is present

Modified: 
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/rules-context.xml
===================================================================
--- 
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/rules-context.xml
      2006-07-15 06:59:08 UTC (rev 1224)
+++ 
trunk/spring-richclient/support/src/test/resources/org/springframework/rules/rules-context.xml
      2006-07-17 10:02:15 UTC (rev 1225)
@@ -7,6 +7,15 @@
        <!-- direct java / groovy / beanshell / jython or some other scripting 
solution is better
             Using the Constraints factory and builders is preferred -->
 
+       <bean id="serviceLocator" 
class="org.springframework.richclient.application.ApplicationServicesLocator">
+           <property name="applicationServices" ref="applicationServices"/>
+       </bean>
+       
+       <bean id="applicationServices"
+           
class="org.springframework.richclient.application.support.DefaultApplicationServices">
+           <property name="rulesSource" ref="rulesSource"/>
+       </bean>
+
        <bean  id="messageSource" 
            
class="org.springframework.context.support.ResourceBundleMessageSource">
          <property name="basenames">
@@ -15,7 +24,7 @@
                </list>
          </property>
        </bean>
-            
+       
        <bean id="rulesSource" 
class="org.springframework.rules.support.DefaultRulesSource">
                <property name="rules">
                        <list>
@@ -59,4 +68,4 @@
        
        <bean id="equals" class="org.springframework.rules.constraint.EqualTo"/>
        <bean id="required" 
class="org.springframework.rules.constraint.Required"/>
-</beans>
\ No newline at end of file
+</beans>


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
spring-rich-c-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spring-rich-c-cvs

Reply via email to