Bonjour,
J'utilise la classe java.utils.Properties et je me rends compte que les EL ne sont pas traduites. Cela signifie-t-il que cette classe n'est pas compatible avec un fichier de propriétés comportant des EL ?
Bonjour,
J'utilise la classe java.utils.Properties et je me rends compte que les EL ne sont pas traduites. Cela signifie-t-il que cette classe n'est pas compatible avec un fichier de propriétés comportant des EL ?
tu pourrais expliquer ce que tu veux faire? Les Expression language est les fichiers properties n'ont rien à voir entre eux.
si ce que tu entends par EL c'est ca :
maProp=maValue
maProp2=${maProp}
effectivement java.util.properties ne le gère pas. Mais par contre commons-configuration le fait très bien.
En même temps ce n'est pas très dur à gérer non plus ! Un petit coup de regexp et c'est dans la poche :
a++
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 class ExtendedProperties extends Properties { /** L'expression régulière qui défini nos éléments : */ private final Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}"); @Override public String getProperty(String key) { String property = super.getProperty(key); if (property!=null) { // On recherche le pattern de l'expression : Matcher matcher = pattern.matcher(property); // Si on trouve au moins un élément : if (matcher.find()) { // On crée un StringBuffer pour générer la nouvelle chaine : StringBuffer sb = new StringBuffer(property.length()); // Puis on traite toutes les éléments trouvés : do { // On récupère la nouvelle clef : String subKey = matcher.group(1); // On récupère la valeur de cette clef : String replacement = getProperty(subKey); // Si la valeur est nulle, on laisse l'expression tel quel : if (replacement==null) { replacement = matcher.group(); } // On effectue le remplacement en ajoutant le tout dans le StringBuffer : matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); } while (matcher.find()); // On concatène la fin de la chaine : matcher.appendTail(sb); // Et on affecte la nouvelle propriété : property = sb.toString(); } } return property; } }
Merci pour vos réponses. Commons-configuration peut-il s'utiliser dans un environnement serveur, stand-alone ou les deux ?
On peut rajouter une petite optimisation à la fin pour empécher le même travail la prochaine fois:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 // On concatène la fin de la chaine : matcher.appendTail(sb); // Et on affecte la nouvelle propriété : property = sb.toString(); //Optimisation pour la prochaine recherche put(key, property); //for next fetch }
Ca dépend de ce que tu veux faire avec ta classe properties, car cela pourrait te fausser le fichier si tu le réenregistres (tu perdrais alors les expressions).
a++
PS : A noter également que mon code ne gère pas du tout les références circulaires, ce qui aboutira à une exception...
Ce que je veux dire, c'est qu'il n'est pas rare de sauvegarder un Properties à la fin de l'application avec la méthode store(), afin de conserver les éventuelles modifications qu'on y a apporté (par exemple pour la configuration d'une application).
Maintenant c'est sûr que cela dépend de l'utilisation qu'on fait de Properties
a++
OK merci, je crois qu'il de quoi faire maintenant. J'y avais pensé à la regex (+-) mais c'est que s'il y a d'autres méthodes à gérer ça alourdi vachement (je sais pas si j'ai tout bien compris). On me dit toujours de ne pas réinventer la roue, mais bon !
Merci les gars![]()
Dans le cas d'une sauvegarde on perdra les lignes dont la valeur contient une EL.. mais ça m'étonnerai (rare) qu'on change un fichier properties à la volée dans une application web ou autres
En tout cas tu peux quand même reconnaitre que c'est une petite optimisation
Pilate : tant qu'une solution réutilisable satisfait au besoin ce n'est pas la peine de la réécrire.
OK j'ai essaye la methode de adiGuba mais il y a un bug (duplication d'une partie de la propriété). Je ne comprends pas ceci :
Normalement, la property finale n'est pas sensé avoir la même longueur que celle contenant les EL !
Code : Sélectionner tout - Visualiser dans une fenêtre à part StringBuffer sb = new StringBuffer(property.length());
Et pis le quoteReplacement, rin compris moi... Mais l'idée étant bonne, je l'ai reprise et ça marche maintenant merci beaucoup. Mon code pour ceux que ça intéresse.
J'ai essayé avec plusieurs EL à la suite et RAS pour l'instant
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package com...; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class ELParserProperties extends Properties { private static final long serialVersionUID = 1L; private static final Log LOG = LogFactory.getLog(ELParserProperties.class); private static final String EL_START = "${"; private static final String EL_END = "}"; @Override public String getProperty(String key) { String property = super.getProperty(key); LOG.trace("property avant traitement : " + property); if (property != null) { while (property.contains(EL_START)) { String beforeSubKey = property.substring(0, property.indexOf(EL_START)); String subKey = property.substring( property.indexOf(EL_START) + EL_START.length(), property .indexOf(EL_END)); String afterSubKey = property.substring(property.indexOf(EL_END) + EL_END.length(), property.length()); LOG.trace(beforeSubKey + "--" + subKey + "--" + afterSubKey); property = beforeSubKey + getProperty(subKey) + afterSubKey; LOG.trace("property apres traitement : " + property); } put(key, property); } return property; } }![]()
Ca crée un stringbuffer avec une taille initiale pour le buffer égale à la longueur de la propriété. Avoir une taille suffisament grande mais pas trop est préférable à la taille par défaut qui est de 13. Le stringbuffer s'agrandira de toutes facons automatiquement si la taille est pas suffisante.
Tu as un exemple des données qui provoque cela ?
Il ne s'agit pas de la taille finale mais de la taille initiale du buffer. Ce dernier est agrandi si besoin
C'est une particularité des regexp. Le chaine de remplacement peut utiliser des caractères spéciaux et quoteReplacement() permet de les ignorer.
a++
Merci pour votre aide et votre éloquence vitales je penses pour ce forum...![]()
Partager