/*
* (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Contributors:
* Anahide Tchertchian
*/
package org.nuxeo.ecm.webapp.seam.messages;
import static org.jboss.seam.annotations.Install.APPLICATION;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.core.SeamResourceBundle;
import org.jboss.seam.international.Messages;
/**
* Factory for a Map that contains interpolated messages defined in the Seam
* ResourceBundle.
* <p>
* Overriden to add a control over reload of bundle for hot reload
*
* @see org.jboss.seam.core.SeamResourceBundle
* @author Gavin King
* @since 5.6
*/
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Name("org.jboss.seam.international.messagesFactory")
// XXX: since debug mode cannot be set by using nuxeo debug/dev mode, make
// sure this component is deployed even in production => debug = false
@Install(precedence = APPLICATION, debug = false)
public class HotReloadMessages extends Messages {
@Override
@SuppressWarnings("rawtypes")
// mostly copy/pasted from parent class
protected Map createMap() {
// AbstractMap uses the implementation of entrySet to perform all its
// operations - for a resource bundle this is very inefficient for keys
return new AbstractMap<String, String>() {
private ResourceBundle seamResourceBundle = getSeamResourceBundle();
/**
* Returns usual seam bundle, but with a custom resource control
*/
protected ResourceBundle getSeamResourceBundle() {
ResourceBundle.Control control = HotReloadResourceBundleControl.instance();
return ResourceBundle.getBundle(SeamResourceBundle.class.getName(),
org.jboss.seam.core.Locale.instance(),
Thread.currentThread().getContextClassLoader(), control);
}
@Override
public String get(Object key) {
if (key instanceof String) {
String resourceKey = (String) key;
String resource = null;
ResourceBundle bundle = seamResourceBundle;
if (bundle != null) {
try {
resource = bundle.getString(resourceKey);
} catch (MissingResourceException mre) {
// Just swallow
}
}
return resource == null ? resourceKey : resource;
} else {
return null;
}
}
@Override
public Set<Map.Entry<String, String>> entrySet() {
ResourceBundle bundle = seamResourceBundle;
Enumeration<String> keys = bundle.getKeys();
Map<String, String> map = new HashMap<String, String>();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
map.put(key, get(key));
}
return Collections.unmodifiableSet(map.entrySet());
}
@Override
public boolean containsKey(Object key) {
return get(key) != null;
}
@Override
public Set<String> keySet() {
ResourceBundle bundle = seamResourceBundle;
Enumeration<String> keys = bundle.getKeys();
return new HashSet<String>(Collections.list(keys));
}
@Override
public int size() {
return keySet().size();
}
};
}
}