Author: bpoussin Date: 2012-03-07 19:42:05 +0100 (Wed, 07 Mar 2012) New Revision: 1446 Url: http://nuiton.org/repositories/revision/wikitty/1446 Log: synchronisation de la map d'alias pour eviter les problemes de parsing Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2012-03-07 18:17:46 UTC (rev 1445) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2012-03-07 18:42:05 UTC (rev 1446) @@ -24,6 +24,7 @@ */ package org.nuiton.wikitty.query; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -71,7 +72,9 @@ /** * Cette classe permet d'interpreter une requete faite textuellement en la - * convertisant en sa representation objet. + * convertisant en sa representation objet. Si l'objet est instancier pour + * utiliser les fonctionnalites d'alias, il est possible de l'utiliser dans + * plusieurs thread concurent. La map d'alias est protegee. * * Pour plus d'information reportez-vous à la * <a href="http://maven-site.nuiton.org/wikitty/user/query.html">documentation</a> @@ -154,20 +157,45 @@ return true; } + /** + * Retourne une vue non modifiable des alias disponibles. + * @return + */ public Map<String, String> getAlias() { - return alias; + return Collections.unmodifiableMap(alias); } + /** + * Modifie l'ensemble des alias, la map passee en parametre est copiee en + * interne. + * @param alias la map des alias qui sera copiee + * @return le WikittyQueryParser lui meme (this) + */ public WikittyQueryParser setAlias(Map<String, String> alias) { - this.alias = alias; + // on passe par la creation d'une nouvelle map, pour eviter que l'utilisateur + // ne puisse modifier les alias depuis l'exterieur et eviter le plus + // possible les synchronize + this.alias = new LinkedHashMap<String, String>(); + if (alias != null) { + this.alias.putAll(alias); + } return this; } public WikittyQueryParser addAlias(String aliasName, String aliasValue) { - alias.put(aliasName, aliasValue); + synchronized(alias) { + alias.put(aliasName, aliasValue); + } return this; } + public WikittyQueryParser clearAlias() { + // on passe par la creation d'une nouvelle map, pour eviter le plus + // possible les synchronize + this.alias = new LinkedHashMap<String, String>(); + return this; + } + /** * Parse query and use alias added with {@link #addAlias} or {@link #setAlias} * @@ -200,9 +228,16 @@ static public WikittyQuery parse(String queryString, Map<String, String> alias) { if (alias != null) { String queryStringInit = queryString; - // first replace alias in queryString - for (Map.Entry<String, String> a : alias.entrySet()) { - queryString = queryString.replaceAll(a.getKey(), a.getValue()); + // on synchronise l'utilisation de la map, pour etre sur qu'il n'y + // ait pas d'ajout/modif durant son utilisation pour le remplacement + // on fait direcement les remplacements de la requete car, c'est + // le seul endroit ou l'alias est utilise, et c'est aussi rapide + // que de faire une copie de la map + synchronized(alias) { + // first replace alias in queryString + for (Map.Entry<String, String> a : alias.entrySet()) { + queryString = queryString.replaceAll(a.getKey(), a.getValue()); + } } if (log.isDebugEnabled()) { log.debug(String.format("QueryString \n'%s' become after alias \n'%s'\naliases are %s",