001    /*******************************************************************************
002     * Portions created by Sebastian Thomschke are copyright (c) 2005-2013 Sebastian
003     * Thomschke.
004     *
005     * All Rights Reserved. This program and the accompanying materials
006     * are made available under the terms of the Eclipse Public License v1.0
007     * which accompanies this distribution, and is available at
008     * http://www.eclipse.org/legal/epl-v10.html
009     *
010     * Contributors:
011     *     Sebastian Thomschke - initial implementation.
012     *******************************************************************************/
013    package net.sf.oval.localization.context;
014    
015    import java.util.Enumeration;
016    import java.util.MissingResourceException;
017    import java.util.ResourceBundle;
018    
019    import net.sf.oval.context.ClassContext;
020    import net.sf.oval.context.ConstructorParameterContext;
021    import net.sf.oval.context.FieldContext;
022    import net.sf.oval.context.MethodEntryContext;
023    import net.sf.oval.context.MethodExitContext;
024    import net.sf.oval.context.MethodParameterContext;
025    import net.sf.oval.context.MethodReturnValueContext;
026    import net.sf.oval.context.OValContext;
027    import net.sf.oval.internal.Log;
028    
029    /**
030     * This renderer searches for a resource file that is in the same package and has the same name as the validated class.
031     * It then tries to lookup a localized version of the validation context, e.g.<br>
032     * <b>com.acme.model.Person.java<br>
033     * com.acme.model.Person.properties<br>
034     * com.acme.model.Person_de.properties<br>
035     * com.acme.model.Person_fr.properties</b>
036     *
037     * <p>
038     * The properties file is expected to have values following this scheme
039     * <pre>
040     * label.class=My translated name of the class name
041     * label.field.firstname=My translated name of the field "firstname"
042     * label.field.lastname=My translated name of the field "lastname"
043     * label.parameter.amount=My translated name of a constructor/method parameter "amount"
044     * label.method.increase=My translated name of the method "increase"
045     * </pre>
046     * @author Sebastian Thomschke
047     */
048    public class ResourceBundleValidationContextRenderer implements OValContextRenderer
049    {
050            private static final Log LOG = Log.getLog(ResourceBundleValidationContextRenderer.class);
051    
052            public static final ResourceBundleValidationContextRenderer INSTANCE = new ResourceBundleValidationContextRenderer();
053    
054            private static boolean containsKey(final ResourceBundle bundle, final String key)
055            {
056                    for (final Enumeration<String> en = bundle.getKeys(); en.hasMoreElements();)
057                            if (en.nextElement().equals(key)) return true;
058                    return false;
059            }
060    
061            /**
062             * {@inheritDoc}
063             */
064            public String render(final OValContext ovalContext)
065            {
066                    final String baseName;
067                    final String key;
068                    if (ovalContext instanceof ClassContext)
069                    {
070                            final ClassContext ctx = (ClassContext) ovalContext;
071                            baseName = ctx.getClazz().getName();
072                            key = "label.class";
073                    }
074                    else if (ovalContext instanceof FieldContext)
075                    {
076                            final FieldContext ctx = (FieldContext) ovalContext;
077                            baseName = ctx.getField().getDeclaringClass().getName();
078                            final String fieldName = ctx.getField().getName();
079                            key = "label.field." + fieldName;
080                    }
081                    else if (ovalContext instanceof ConstructorParameterContext)
082                    {
083                            final ConstructorParameterContext ctx = (ConstructorParameterContext) ovalContext;
084                            baseName = ctx.getConstructor().getDeclaringClass().getName();
085                            key = "label.parameter." + ctx.getParameterName();
086                    }
087                    else if (ovalContext instanceof MethodParameterContext)
088                    {
089                            final MethodParameterContext ctx = (MethodParameterContext) ovalContext;
090                            baseName = ctx.getMethod().getDeclaringClass().getName();
091                            key = "label.parameter." + ctx.getParameterName();
092                    }
093                    else if (ovalContext instanceof MethodEntryContext)
094                    {
095                            final MethodEntryContext ctx = (MethodEntryContext) ovalContext;
096                            baseName = ctx.getMethod().getDeclaringClass().getName();
097                            key = "label.method." + ctx.getMethod().getName();
098                    }
099                    else if (ovalContext instanceof MethodExitContext)
100                    {
101                            final MethodExitContext ctx = (MethodExitContext) ovalContext;
102                            baseName = ctx.getMethod().getDeclaringClass().getName();
103                            key = "label.method." + ctx.getMethod().getName();
104                    }
105                    else if (ovalContext instanceof MethodReturnValueContext)
106                    {
107                            final MethodReturnValueContext ctx = (MethodReturnValueContext) ovalContext;
108                            baseName = ctx.getMethod().getDeclaringClass().getName();
109                            key = "label.method." + ctx.getMethod().getName();
110                    }
111                    else
112                            return ovalContext.toString();
113    
114                    try
115                    {
116                            final ResourceBundle bundle = ResourceBundle.getBundle(baseName);
117                            if (containsKey(bundle, key)) return bundle.getString(key);
118                            LOG.debug("Key {1} not found in bundle {2}", key, baseName);
119                    }
120                    catch (final MissingResourceException ex)
121                    {
122                            LOG.debug("Bundle {1} not found", baseName, ex);
123                    }
124                    return ovalContext.toString();
125            }
126    }