/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.structure; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.io.FileSystemResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Component; import com.enonic.cms.store.dao.SiteDao; @Component("sitePropertiesService") public class SitePropertiesServiceImpl implements SitePropertiesService, ApplicationListener { private static final Logger LOG = LoggerFactory.getLogger( SitePropertiesService.class ); private Properties defaultProperties; private final Map<SiteKey, SiteProperties> sitePropertiesMap = new ConcurrentHashMap<SiteKey, SiteProperties>(); private File homeDir; private ResourceLoader resourceLoader = new FileSystemResourceLoader(); private SiteDao siteDao; private List<SitePropertiesListener> sitePropertiesListeners = new ArrayList<SitePropertiesListener>(); private boolean started = false; @Override public void registerSitePropertiesListener( final SitePropertiesListener listener ) { LOG.info( "Registered site properties listener: " + listener.getClass().getSimpleName() ); sitePropertiesListeners.add( listener ); } @Override public void onApplicationEvent( final ApplicationEvent event ) { if ( event instanceof ContextRefreshedEvent ) { start(); } } public void restart() { stop(); start(); } public void stop() { sitePropertiesMap.clear(); started = false; } public void start() { if ( started ) { return; } Resource resource = resourceLoader.getResource( "classpath:com/enonic/cms/business/render/site-default.properties" ); try { defaultProperties = new Properties(); defaultProperties.load( resource.getInputStream() ); } catch ( IOException e ) { throw new RuntimeException( "Failed to load site-default.properties", e ); } // Load properties for all sites final List<SiteEntity> allSites = siteDao.findAll(); for ( final SiteEntity currSite : allSites ) { loadSiteProperties( currSite.getKey() ); } // Broadcast properties loaded for all sites for ( final SiteEntity currSite : allSites ) { final SiteProperties siteProperties = sitePropertiesMap.get( currSite.getKey() ); for ( SitePropertiesListener listener : sitePropertiesListeners ) { listener.sitePropertiesLoaded( siteProperties ); } } started = true; } public SiteProperties getSiteProperties( SiteKey siteKey ) { final SiteProperties siteProperties = doGetSiteProperties( siteKey ); if ( siteProperties == null ) { throw new IllegalArgumentException( "No properties for site " + siteKey ); } return siteProperties; } private String getProperty( String key, SiteKey siteKey ) { SiteProperties props = doGetSiteProperties( siteKey ); if ( props == null ) { throw new IllegalArgumentException( "No properties for site " + siteKey ); } return props.getProperty( key ); } public String getSiteProperty( SiteKey siteKey, SitePropertyNames key ) { return getSiteProperties( siteKey ).getProperty( key.getKeyName() ); } public Boolean getPropertyAsBoolean( SitePropertyNames key, SiteKey siteKey ) { String svalue = getProperty( key.getKeyName(), siteKey ); return svalue == null ? Boolean.FALSE : Boolean.valueOf( svalue ); } private SiteProperties doGetSiteProperties( final SiteKey siteKey ) { SiteProperties props; synchronized ( sitePropertiesMap ) { props = sitePropertiesMap.get( siteKey ); if ( props == null ) { props = loadSiteProperties( siteKey ); } } return props; } public void reloadSiteProperties( final SiteKey siteKey ) { synchronized ( sitePropertiesMap ) { loadSiteProperties( siteKey ); final SiteProperties siteProperties = sitePropertiesMap.get( siteKey ); for ( SitePropertiesListener listener : sitePropertiesListeners ) { listener.sitePropertiesReloaded( siteProperties ); } } } private SiteProperties loadSiteProperties( final SiteKey siteKey ) { final Properties properties = new Properties( defaultProperties ); final String relativePathToCmsHome = "/config/site-" + siteKey + ".properties"; String propertiesType = "default"; try { final String resourcePath = this.homeDir.toURI().toURL() + relativePathToCmsHome; final Resource resource = resourceLoader.getResource( resourcePath ); if ( resource.exists() ) { final InputStream stream = resource.getInputStream(); properties.load( stream ); stream.close(); propertiesType = "custom"; } } catch ( IOException e ) { throw new RuntimeException( "Failed to load site properties file: " + relativePathToCmsHome, e ); } LOG.info( "Loaded {} properties for site #{}", propertiesType, siteKey ); final SiteProperties siteProperties = new SiteProperties( siteKey, properties ); sitePropertiesMap.put( siteKey, siteProperties ); return siteProperties; } @Value("${cms.home}") public void setHomeDir( File homeDir ) { this.homeDir = homeDir; } public void setResourceLoader( ResourceLoader resourceLoader ) { this.resourceLoader = resourceLoader; } @Autowired public void setSiteDao( final SiteDao siteDao ) { this.siteDao = siteDao; } }