2013-08-04 5 views
1

Я хочу перезагрузить/обновить свой ресурс после обновления данных.JSF Reload resource bundle on Glassfish 3.1.2

Моя ResourceBundle реализация основана на дб, вот код:

public class DatabaseResourceBundle extends ResourceBundle { 

    private static EntityManagerFactory factory = Persistence.createEntityManagerFactory("ADAEcommerceEjbPU"); 
    private EntityManager _entityManager = factory.createEntityManager(); 
    private Map<String, String> _values = new HashMap<>(); 
    protected final static String BUNDLE_NAME = "com.infomaxgroup.adaecommerce.bundles"; 
    private final static Logger LOGGER = Logger.getLogger(DatabaseResourceBundle.class.getName()); 
    private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale(); 
    protected Control DB_CONTROL = new DBControl(); 

    /** 
    * Public constructor setting the parent bundle 
    */ 
    public DatabaseResourceBundle() { 
    LOGGER.log(Level.FINE, "DatabaseResourceBundle()"); 
    setParent(ResourceBundle.getBundle(BUNDLE_NAME, 
      FacesContext.getCurrentInstance().getViewRoot().getLocale(), DB_CONTROL)); 
    } 

    public DatabaseResourceBundle(Locale locale) { 
    LOGGER.log(Level.FINE, "DatabaseResourceBundle(Locale locale)"); 
    setParent(ResourceBundle.getBundle(BUNDLE_NAME, locale, DB_CONTROL)); 
    } 

    @Override 
    protected Object handleGetObject(String key) { 
    LOGGER.log(Level.FINE, "handleGetObject() Locale {0} Key: {1} ", new Object[]{locale.toString(), key}); 
    return _values != null ? _values.get(key) : parent.getObject(key); 
    } 

    @Override 
    public Enumeration<String> getKeys() { 
    LOGGER.log(Level.FINE, "getKeys() Parent Locale {0} ", parent.getLocale()); 
    return parent.getKeys(); 
    } 

    /** 
    * The Control Callback. 
    * 
    * @see 
    * http://docs.oracle.com/javase/6/docs/api/java/util/ResourceBundle.Control.html 
    */ 
    protected class DBControl extends Control { 

    @Override 
    public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) 
      throws IllegalAccessException, InstantiationException, IOException { 
     LOGGER.log(Level.INFO, "reload {0} ", reload); 
     return new MyResources(locale); 
    } 

    /** 
    * A simple ListResourceBundle 
    */ 
    protected class MyResources extends ListResourceBundle { 

     private Locale locale; 

     /** 
     * ResourceBundle constructor with locale 
     * 
     * @param locale 
     */ 
     public MyResources(Locale locale) { 
     this.locale = locale; 
     } 

     @Override 
     protected Object[][] getContents() { 
     if (locale == null) { 
      locale = Locale.ITALY; 
     } 

     TypedQuery<ResourceEntity> query = _entityManager.createNamedQuery("ResourceEntity.findForLocale", ResourceEntity.class); 
     query.setParameter("locale", locale.getLanguage()); 

     List<ResourceEntity> resources = query.getResultList(); 

     Object[][] all = new Object[resources.size()][2]; 
     int i = 0; 
     for (Iterator<ResourceEntity> it = resources.iterator(); it.hasNext();) { 
      ResourceEntity resource = it.next(); 
      all[i] = new Object[]{resource.getKey(), resource.getValue()}; 
      _values.put(resource.getKey(), resource.getValue()); 
      i++; 
     } 
     return all; 
     } 
    } 
    } 
} 

Когда я обновить данные и вызвать DatabaseResourceBundle.clearCache() Я вижу, что следующий запрос вызывает метод:

MyResources.getContents() 

Если я отлаживать то, что данные возвращаются в

Object[][] all 

здесь я вижу но на странице JSF я все еще вижу старые данные, похоже, что JSF использует кэшированные данные.

Как просмотреть обновленные данные на странице JSF?

Большое спасибо заранее ...

+0

какой сервер приложений вы используете? –

+0

Glassfish 3.1.2 см. Вопрос название;) – giates

+0

Ой, справа, только сосредоточен на тексте ... Так что я не уверен, что это то, что я видел еще, но его можно ввести ресурсы аннотациями. Не уверен, что это возможно с помощью пакетов ресурсов на основе db. Эти ресурсы могут быть перезагружены с помощью поиска jndi: https://blogs.oracle.com/chengfang/entry/how_to_inject_and_look –

ответ

0

Проблема была решена с шагами ниже:

1) после модификации (вставка, обновление, удаление) любого ResourceEntity я называю

DatabaseResourceBundle.clearCache(); 

2) Если я хочу, чтобы обновить ярлыки ресурсов JSF я называю этот код (предлагаемый код приходит от: How to reload resource bundle in web application?):

ApplicationResourceBundle applicationBundle = ApplicationAssociate.getCurrentInstance().getResourceBundles().get("msg"); 
    Field field = null; 
    try { 
    field = applicationBundle.getClass().getDeclaredField("resources"); 
    } catch (NoSuchFieldException | SecurityException ex) { 
    Logger.getLogger(UserRegistrationController.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    if (field != null) { 
    field.setAccessible(true); 
    Map<Locale, ResourceBundle> resources = null; 
    try { 
     resources = (Map<Locale, ResourceBundle>) field.get(applicationBundle); 
    } catch (IllegalArgumentException | IllegalAccessException ex) { 
     Logger.getLogger(UserRegistrationController.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    if (resources != null) { 
     resources.clear(); 
    } 
    } 

Надеюсь, это поможет ...