001/*
002 *  Copyright 2013 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.core.cocoon;
017
018import java.util.Locale;
019import java.util.Map;
020
021import org.apache.avalon.framework.activity.Initializable;
022import org.apache.avalon.framework.component.ComponentException;
023import org.apache.avalon.framework.configuration.Configuration;
024import org.apache.avalon.framework.configuration.ConfigurationException;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027
028import org.ametys.core.DevMode;
029import org.ametys.core.DevMode.DEVMODE;
030import org.ametys.core.ObservationConstants;
031import org.ametys.core.observation.Event;
032import org.ametys.core.observation.ObservationManager;
033import org.ametys.core.observation.Observer;
034import org.ametys.core.util.I18nUtils;
035
036/**
037 * This XMLResourceBundleFactory creates a <code>Bundle</code> for XML resources which can be invalidated
038 */
039public class XMLResourceBundleFactory extends org.apache.cocoon.i18n.XMLResourceBundleFactory implements Observer, Initializable
040{
041    private ObservationManager _observationManager;
042    
043    @Override
044    public void service(ServiceManager smanager) throws ServiceException 
045    {
046        super.service(smanager);
047        
048        if (smanager.hasService(ObservationManager.ROLE))
049        {
050            _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE);
051        }
052    }
053    
054    @Override
055    public void configure(Configuration configuration) throws ConfigurationException
056    {
057        super.configure(configuration);
058        
059        // never reload in production, always reload in development
060        interval = DevMode.getDeveloperMode() == DEVMODE.PRODUCTION ? -1 : 0;
061    }
062    
063    public void initialize() throws Exception
064    {
065        if (_observationManager != null)
066        {
067            _observationManager.registerObserver(this);
068        }
069    }
070    
071    @Override
072    protected org.apache.cocoon.i18n.XMLResourceBundle create(String sourceURI, Locale locale, org.apache.cocoon.i18n.XMLResourceBundle parent)
073    {
074        if (getLogger().isDebugEnabled()) 
075        {
076            getLogger().debug("Creating bundle <" + sourceURI + ">");
077        }
078
079        XMLResourceBundle bundle = new XMLResourceBundle(sourceURI, locale, parent);
080        bundle.enableLogging(getLogger());
081        bundle.reload(manager, resolver, interval);
082        return bundle;
083    }
084    
085    /**
086     * Invalidate catalogue 
087     * @param location catalogue base location (URI)
088     * @param name bundle name
089     * @param localeName  locale name
090     * @throws ComponentException If an error occurred
091     */
092    public void invalidateCatalogue (String location, String name, String localeName) throws ComponentException
093    {
094        String cacheKey = "XRB" + getCacheKey(new String[] {location}, 0, name, new Locale(localeName));
095        cache.remove(cacheKey);
096    }
097    
098    public int getPriority(Event event)
099    {
100        return MIN_PRIORITY;
101    }
102    
103    public boolean supports(Event event)
104    {
105        return event.getId().equals(ObservationConstants.EVENT_CACHE_RESET)
106               && I18nUtils.I18N_CACHE.equals(event.getArguments().get(ObservationConstants.ARGS_CACHE_ID));
107    }
108    
109    public void observe(Event event, Map<String, Object> transientVars) throws Exception
110    {
111        // also clear the bundle cache when clearing the i18n cache 
112        cache.clear();
113    }
114}