Author: fmeschbe
Date: Mon Apr 4 12:00:21 2011
New Revision: 1088573
URL: http://svn.apache.org/viewvc?rev=1088573&view=rev
Log:
SLING-2047 Always fully load the resources when the JcrResourceBundle is
created for the locale.
Modified:
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundle.java
Modified:
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundle.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundle.java?rev=1088573&r1=1088572&r2=1088573&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundle.java
(original)
+++
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundle.java
Mon Apr 4 12:00:21 2011
@@ -27,11 +27,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
import javax.jcr.query.Query;
-import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.slf4j.Logger;
@@ -49,46 +46,22 @@ public class JcrResourceBundle extends R
private static final String PROP_BASENAME = "sling:basename";
- /**
- * Search the tree below a mix:language node matching a given language...
- */
- private static final String QUERY_BASE =
-
"//element(*,mix:language)[@jcr:language='%s'%s]//element(*,sling:Message)";
-
- /**
- * ... and find all nodes with a sling:message property set
- * (typically with mixin sling:Message).
- */
- private static final String QUERY_LOAD_FULLY = QUERY_BASE
- + "[@" + PROP_VALUE + "]/(@" + PROP_KEY + "|@" + PROP_VALUE + ")";
-
- /**
- * ... or find a node with the message (sling:message property) for
- * a given key (sling:key property). Also find nodes without sling:key
- * property and examine their node name.
- */
- private static final String QUERY_LOAD_RESOURCE = QUERY_BASE + "[@"
- + PROP_KEY + "='%s' or not(@" + PROP_KEY + ")]/(@" + PROP_KEY + "|@" +
PROP_VALUE + ")";
-
- private final ResourceResolver resourceResolver;
-
- private final ConcurrentHashMap<String, Object> resources;
-
- private boolean fullyLoaded;
+ private final HashMap<String, Object> resources;
private final Locale locale;
- private final String baseName;
-
- private String[] searchPath;
-
JcrResourceBundle(Locale locale, String baseName,
ResourceResolver resourceResolver) {
this.locale = locale;
- this.baseName = baseName;
- this.resourceResolver = resourceResolver;
- this.resources = new ConcurrentHashMap<String, Object>();
- this.fullyLoaded = false;
+
+ long start = System.currentTimeMillis();
+ final String loadQuery = getFullLoadQuery(locale, baseName);
+ this.resources = loadFully(resourceResolver, loadQuery);
+ long end = System.currentTimeMillis();
+ log.debug(
+ "JcrResourceBundle: Fully loaded {} entries for {} (base: {}) in
{}ms",
+ new Object[] { resources.size(), locale, baseName,
+ (end - start) });
}
@Override
@@ -110,17 +83,11 @@ public class JcrResourceBundle extends R
* @return The keys of the resources provided by this resource bundle
*/
protected Set<String> handleKeySet() {
- // ensure all keys are loaded
- loadFully();
-
return resources.keySet();
}
@Override
public Enumeration<String> getKeys() {
- // ensure all keys are loaded
- loadFully();
-
Enumeration<String> parentKeys = (parent != null)
? parent.getKeys()
: null;
@@ -130,146 +97,74 @@ public class JcrResourceBundle extends R
@Override
protected Object handleGetObject(String key) {
Object value = resources.get(key);
- if (value == null && !fullyLoaded) {
- value = loadResource(key);
- if (value != null) {
- resources.put(key, value);
- }
- }
-
- return (value != null) ? value : key;
+ return (value == null) ? key : value;
}
- private void loadFully() {
- if (!fullyLoaded) {
-
- synchronized (this) {
- if (!fullyLoaded) {
-
- final String fullLoadQuery = getFullLoadQuery();
- if (log.isDebugEnabled()) {
- log.debug("Executing full load query {}",
fullLoadQuery);
- }
- Iterator<Map<String, Object>> bundles =
resourceResolver.queryResources(
- fullLoadQuery, Query.XPATH);
-
- String[] path = getSearchPath();
+ private HashMap<String, Object> loadFully(
+ final ResourceResolver resourceResolver, final String
fullLoadQuery) {
+ log.debug("Executing full load query {}", fullLoadQuery);
- List<Map<String, Object>> res0 = new ArrayList<Map<String,
Object>>();
- for (int i = 0; i < path.length; i++) {
- res0.add(new HashMap<String, Object>());
- }
- Map<String, Object> rest = new HashMap<String, Object>();
+ // do an XPath query because this won't go away soon and still
+ // (2011/04/04) is the fastest query language ...
+ @SuppressWarnings("deprecation")
+ Iterator<Map<String, Object>> bundles =
resourceResolver.queryResources(
+ fullLoadQuery, Query.XPATH);
- while (bundles.hasNext()) {
- Map<String, Object> row = bundles.next();
- String jcrPath = (String) row.get(JCR_PATH);
- String key = (String) row.get(PROP_KEY);
+ String[] path = resourceResolver.getSearchPath();
- if (key == null) {
- key = ResourceUtil.getName(jcrPath);
- }
-
- Map<String, Object> dst = rest;
- for (int i = 0; i < path.length; i++) {
- if (jcrPath.startsWith(path[i])) {
- dst = res0.get(i);
- break;
- }
- }
-
- dst.put(key, row.get(PROP_VALUE));
- }
+ List<HashMap<String, Object>> res0 = new ArrayList<HashMap<String,
Object>>();
+ for (int i = 0; i < path.length; i++) {
+ res0.add(new HashMap<String, Object>());
+ }
+ HashMap<String, Object> rest = new HashMap<String, Object>();
- for (int i = path.length - 1; i >= 0; i--) {
- rest.putAll(res0.get(i));
- }
+ while (bundles.hasNext()) {
+ Map<String, Object> row = bundles.next();
+ String jcrPath = (String) row.get(JCR_PATH);
+ String key = (String) row.get(PROP_KEY);
- resources.putAll(rest);
+ if (key == null) {
+ key = ResourceUtil.getName(jcrPath);
+ }
- fullyLoaded = true;
+ Map<String, Object> dst = rest;
+ for (int i = 0; i < path.length; i++) {
+ if (jcrPath.startsWith(path[i])) {
+ dst = res0.get(i);
+ break;
}
}
- }
- }
- private Object loadResource(String key) {
- final String resourceQuery = getResourceQuery(key);
- if (log.isDebugEnabled()) {
- log.debug("Executing resource query {}", resourceQuery);
+ dst.put(key, row.get(PROP_VALUE));
}
- Iterator<Map<String, Object>> bundles = resourceResolver
- .queryResources(resourceQuery, Query.XPATH);
- if (bundles.hasNext()) {
-
- String[] path = getSearchPath();
-
- Map<String, Object> currentValue = null;
- int currentWeight = path.length;
-
- while (bundles.hasNext() && currentWeight > 0) {
- Map<String, Object> resource = bundles.next();
- String jcrPath = (String) resource.get(JCR_PATH);
-
- // skip resources without sling:key and non-matching nodename
- if (resource.get(PROP_KEY) == null) {
- if (!key.equals(Text.getName(jcrPath))) {
- continue;
- }
- }
-
- for (int i = 0; i < currentWeight; i++) {
- if (jcrPath.startsWith(path[i])) {
- currentWeight = i;
- currentValue = resource;
- break;
- }
- }
-
- // the path is not listed, check the current resource if
- // none has yet been set
- if (currentValue == null) {
- currentValue = resource;
- }
- }
- if (currentValue != null) {
- return currentValue.get(PROP_VALUE);
- }
+ for (int i = path.length - 1; i >= 0; i--) {
+ rest.putAll(res0.get(i));
}
- return null;
+ return rest;
}
- private String getFullLoadQuery() {
- return String.format(QUERY_LOAD_FULLY, getLocale(), getBaseNameTerm());
- }
+ private static String getFullLoadQuery(final Locale locale,
+ final String baseName) {
+ StringBuilder buf = new StringBuilder(64);
- private String getResourceQuery(String key) {
- return String.format(QUERY_LOAD_RESOURCE, getLocale(),
- getBaseNameTerm(), key.replace("'", "''"));
- }
+ buf.append("//element(*,mix:language)[@jcr:language='");
+ buf.append(locale);
+ buf.append('\'');
- private String getBaseNameTerm() {
- if (baseName == null) {
- return "";
+ if (baseName != null) {
+ buf.append(" and @");
+ buf.append(PROP_BASENAME);
+ if (baseName.length() > 0) {
+ buf.append("='").append(baseName).append('\'');
+ }
}
- StringBuilder buf = new StringBuilder(" and @");
- buf.append(PROP_BASENAME);
-
- if (baseName.length() > 0) {
- buf.append("='").append(baseName).append('\'');
- }
+ buf.append("]//element(*,sling:Message)");
+ buf.append("[@").append(PROP_VALUE).append("]/(@");
+ buf.append(PROP_KEY).append("|@").append(PROP_VALUE).append(")");
return buf.toString();
}
-
- private String[] getSearchPath() {
- if (searchPath == null) {
- searchPath = resourceResolver.getSearchPath();
- }
-
- return searchPath;
- }
}