[rd_jsfsquad] Re: Bemerkingen extval-poc

  • From: Sander De Vos <de.vos.sander@xxxxxxxxx>
  • To: rd_jsfsquad@xxxxxxxxxxxxx
  • Date: Wed, 17 Feb 2010 11:49:16 +0100

Steve,

In bijlaage de classes die ik gebruik om resourcebundles aan te spreken. Ik
kan  bundles aanspreken via een EL-expressie:
#{I18n.messages['action.course.view']}. Dit is wel spring specifiek dat ik
de messageFactory laat injecteren. Op dezelfde manier kan je de I18n bean
gebruiken maar de map kan je laten initialiseren hoe je wil...

Hier kan je meer lezen over managed beans :
http://www.oracle.com/technology/tech/java/newsletter/articles/jsf_pojo/index.html

As you can define the lifecycle of the beans using the scope setting, you
must take care to only refer to other beans which exist either the same
scope or larger scope. You can not refer to another managed bean with a
smaller scope.
 Managed beans registered with scope: Can only refer to other managed beans
with these scopes:  none none  request none, request, session, application
session none, session, application  application none, application

Mvg,

Sander

2010/2/17 Steve Schols <steve.schols@xxxxxxxxx>

> Dag Rudy,
>
> Kan je mij op weg helpen met die "iets gebaseerd op een EL expressie"?
>
> Ik vind zoveel verschillende dingen terug dat ik het bos door de bomen niet
> meer zie.
> Er waren constraints hierop dacht ik, dat je enkel iets mocht injecteren
> via managed-property dat in een hogere scope lag dan de bean waarin je
> injecteert ... dacht ik, of omgekeerd. Ik vind het niet meer terug via
> google.
>
> Zowel voor MessageUtils als voor PersonBean zou ik niet echt weten hoe dit
> precies met EL dient te gebeuren...
>
>
> Op 6 februari 2010 15:02 schreef Rudy De Busscher <rdebusscher@xxxxxxxxx>het 
> volgende:
>
> Steve,
>>
>> Ik heb de laatste week heel weinig tijd gehad, maar ben toch eens
>> diagonaal door je code gelopen.  Hieronder heb ik een lijstje gemaakt van
>> enkele belangrijke punten. Dit zijn geen absolute waarheden maar kunnen je
>> problemen besparen of zijn geinspireerd op enkele best practices.
>> Als er vragen hierover zijn, laat maar horen.
>>
>> Zal over een tweetal weken nog eens proberen de code te overlopen.
>>
>> groeten
>> Rudy.
>>
>> -Je hebt 2 logging frameworks, probeer commons logging overboord te
>> gooien. (Ik zet het al bij de Questions voor volgende vergadering, over het
>> hoe en waarom)
>>
>> *MessageUtils*
>> - Dit is een Myfaces specifieke klasse dus kan je niet switchen naar
>> Mojarra.
>> - Hierdoor moest je de resource bundle ook tweemaal specifieren, eenmaal
>> in faces-config en eenmal in de Constants klasse.
>> ==> gebruik dus liever iets wat gebaseerd is op een EL expressie.
>>
>> *UserBean*
>> - Is op sessie en is goed om user authenticatie data bij te houden.  Maar
>> bevat ook data welke eigenlijk op applicatie niveau (de predefined users)
>> horen.
>> Het is daarom beter een andere backing bean te maken, op scope
>> application, welke de users bijhoud maar ook zal bepalen of username en
>> paswoord correct zijn. Deze kan dan in de userBean geinjecteerd worden.
>> - de methode authenticate is een action methode.  Deze dient in principe
>> enkel om de navigatie te bepalen, niet de logica welke uitgevoerd moet
>> worden bij een klik.  Dit moet in principe in de actionListener.
>> - Je hebt een navigatie constante gedefinieerd om op de pagina zelf te
>> blijven, return van null is voldoende en deze moet niet in
>> faces-config-navigation gespecifieerd worden.
>>
>> *xxx.jsf*
>> - Wanneer je een lege cel wenst aan te maken in een panelgrid volstaat
>> <f:verbatim/> op de plaats en is <panelGroup> niet nodig.
>> - In je link naar de CSS gebruik je de root, als er een war gemaakt wordt
>> en deze app wordt onder een andere root gedeployed dan wordt de CSS niet
>> gevonden. gebruik altijd relatieve paden.
>>
>> Het is beter dat je de action methoden en actionListeners voor een pagina
>> bij de bean houdt waarin de data staan.  Dus de personBean niet gebruiken
>> voor personList.jsp
>>
>> PersonListBean moet inderdaad op session staan om de sortering van de
>> tabel mogelijk te maken. -> Jan dit is iets voor je Conversation scope in
>> CDI.
>>
>> *PersonBean*
>> - Dit kan je op request niveau plaatsen (zo veel mogelijk op request). Je
>> hebt dan wel een probleempje op te lossen omdat PersonBean niet in
>> PersonListBean kan geinjecteerd worden maar daarvoor bestaat er een
>> oplossing (weeral via EL)
>>
>> **
>>
>>
>
package com.realdolmen.demo.jbpm.web.i18n;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * {@link Map} enabling dynamic return of value by key.
 * 
 * @param <K>
 *              the key
 * @param <V>
 *              the (dynamic) value
 * 
 * @author Yoeri Roels
 */
public class DynamicMap<K, V> implements Map<K, V> {

    /** The {@link DynamicMapValueResolver}. */
    private DynamicMapValueResolver<K, V> valueResolver;

    /**
     * Creates a dynamic {@link Map}.
     * 
     * @param valueResolver
     *          the {@link DynamicMapValueResolver}
     */
    public DynamicMap(final DynamicMapValueResolver<K, V> valueResolver) {
        this.valueResolver = valueResolver;
    }

    /**
     * {@inheritDoc}
     */
    public V get(final Object key) {
        return valueResolver.resolve((K) key);
    }

    /**
     * {@inheritDoc}
     */
    public V put(final K key, final V value) {
        throw new UnsupportedOperationException("put not supported");
    }

    /**
     * {@inheritDoc}
     */
    public void putAll(final Map<? extends K, ? extends V> m) {
        throw new UnsupportedOperationException("putAll not supported");
    }

    /**
     * {@inheritDoc}
     */
    public V remove(final Object key) {
        throw new UnsupportedOperationException("remove not supported");
    }

    /**
     * {@inheritDoc}
     */
    public void clear() {
        throw new UnsupportedOperationException("clear not supported");
    }

    /**
     * {@inheritDoc}
     */
    public Set<K> keySet() {
        throw new UnsupportedOperationException("keySet not supported");
    }

    /**
     * {@inheritDoc}
     */
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        throw new UnsupportedOperationException("entrySet not supported");
    }

    /**
     * {@inheritDoc}
     */
    public Collection<V> values() {
        throw new UnsupportedOperationException("values not supported");
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsKey(final Object key) {
        throw new UnsupportedOperationException("containsKey not supported");
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsValue(final Object value) {
        throw new UnsupportedOperationException("containsValue not supported");
    }

    /**
     * {@inheritDoc}
     */
    public int size() {
        throw new UnsupportedOperationException("size not supported");
    }

    /**
     * {@inheritDoc}
     */
    public boolean isEmpty() {
        throw new UnsupportedOperationException("isEmpty not supported");
    }

}
package com.realdolmen.demo.jbpm.web.i18n;

/**
 * Interface defining the contract for a {@link DynamicMap} value resolver.
 * 
 * @param <K>
 *              the key
 * @param <V>
 *              the (resolved) value
 * 
 * @author Yoeri Roels
 */
public interface DynamicMapValueResolver<K, V> {

    /**
     * Resolves the value using the given key.
     * 
     * @param key
     *          the key
     * 
     * @return
     *          the (resolved) value
     */
    V resolve(K key);

}
package com.realdolmen.demo.jbpm.web.i18n;

import java.util.Map;

import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;

public class I18n {

    /** The messages. */
    private Map<String, String> messages;

    /** The {@link MessageSource}. */
    private MessageSource messageSource;
    
    /** The allow missing messages. */
    private boolean allowMissingMessages;

    /**
     * Creates a {@link MessageSource} Managed Bean.
     */
    public I18n() {
        DynamicMapValueResolver<String, String> messageResolver = new 
DynamicMapValueResolver<String, String>() {
            public String resolve(String key) {
                try {
                        return messageSource.getMessage(key, null, 
LocaleContextHolder.getLocale());
                } catch(NoSuchMessageException e) {
                        if(allowMissingMessages) {
                                return key;
                        } else {
                                throw e;
                        }
                }
            }
        };
        messages = new DynamicMap<String, String>(messageResolver);
    }

    /**
     * Gets the messages.
     * 
     * @return
     *          the messages
     */
    public Map<String, String> getMessages() {
        return messages;
    }

    /**
     * Gets the {@link MessageSource}.
     * 
     * @return 
     *          the {@link MessageSource}
     */
    public MessageSource getMessageSource() {
        return messageSource;
    }

    /**
     * Sets the {@link MessageSource}.
     * 
     * @param messageSource
     *          the {@link MessageSource}
     */
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    /**
     * Gets if missing messages are allowed. <br />
     * Missing messages will fall back to the key.
     * 
     * @return
     *          if missing messages are allowed
     */
        public boolean isAllowMissingMessages() {
                return allowMissingMessages;
        }

        /**
         * Sets if missing messages are allowed. <br />
     * Missing messages will fall back to the key.
         * 
         * @param allowMissingMessages
         *              if missing messages are allowed
         */
        public void setAllowMissingMessages(boolean allowMissingMessages) {
                this.allowMissingMessages = allowMissingMessages;
        }
}

Other related posts: