Come sovrascrivere alcune risorse da un PropertyResourceBundle
-
19-08-2019 - |
Domanda
Ho un sito Web Java / JSF esistente tutto il testo sullo schermo proviene dai file delle proprietà tramite < f: loadBundle basename = " org.example.applicaltion " var = quot &; & applicaltion quot; / Gt &; che estrae il testo da applicaltion.properties.
Per un sottoinsieme configurabile in fase di esecuzione di questi, desidero estrarre la stringa da altrove (CMS tramite servizi Web). Guardando la classe ResourceBundle sembra avere un'infrastruttura per qualcosa di simile a questo con delega a un ResourceBundle padre.
Voglio qualcosa del genere
public class Applicaltion extends ResourceBundle{
@Override
protected Object handleGetObject(String key) {
if(overridenKey(key)){
return overridedValue(key);
}
return null; // ResourceBundle.getObject will delegate to parent
// if we return null
}
}
Ho provato questo e genitore è nullo, suppongo che questo sia più usato nel caso di default - > en - > it_IT.
Sto considerando l'opzione non molto allettante di avere un file diverso dal file delle proprietà personalizzato dal file delle risorse personalizzato e quindi delegare l'intero stack di ResourceBundle.getBundle (PROPERTY_FILE_NAME) .getString (chiave) dall'interno di CustomResourceBundle.handleGetObject (chiave) .
Qualche idea migliore?
Soluzione
Ho finito per risolvere questo problema controllando se avevamo un valore di sostituzione, se lo avessimo restituito, altrimenti delegando al pacchetto di risorse standard
public class UILabels extends ResourceBundle {
private ResourceBundle getFileResources(){
return ResourceBundle.getBundle("com.example.web.UILabelsFile", this.getLocale());
}
public Enumeration<String> getKeys() {
return getFileResources().getKeys();
}
protected Object handleGetObject(String key) {
if(overrideValue(key)){
return getOverridenValue(key);
}
return getFileResources().getObject(key);
}
}
Nota che la leggera differenza nella classe del nome è UILabels, che è ciò che tutti i client useranno il file è UILabelsFile, quindi il caricatore ResourceBundle non ricorre.
Altri suggerimenti
È possibile scrivere un PropertyResolver personalizzato e quindi fare in modo che esegua la logica di dove estrarre i valori delle proprietà.
Ad esempio, è possibile definire un bean chiamato messageSource
e caricare tale application.properties, oltre alle proprietà CMS o qualsiasi altra cosa si abbia.
Quindi scrivi un personalizzato PropertyResolver
(c'è un esempio di come farlo con MessageSource di Spring qui ) e collegalo al tuo faces-config.xml
usando qualcosa del genere:
<application>
<property-resolver>
com.package.MessageSourcePropertyResolver
</property-resolver>
</application>