/* * Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved * http://www.griddynamics.com * * This library is free software; you can redistribute it and/or modify it under the terms of * the Apache License; either * version 2.0 of the License, or any later version. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.griddynamics.jagger.util; import com.griddynamics.jagger.exception.TechnicalException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.io.Resource; import org.springframework.util.StringUtils; import java.io.IOException; import java.util.List; import java.util.Properties; /** * Repository that stores two sets of properties: root properties and regular properties. * Root properties can substituted into regular properties. */ public class PropertiesResolverRegistry implements ApplicationContextAware { private static final Logger log = LoggerFactory.getLogger(PropertiesResolverRegistry.class); private ApplicationContext context; private Properties properties = new Properties(); private Properties priorityProperties = new Properties(); public void addProperty(String name, String value) { priorityProperties.setProperty(name, value); } public String getProperty(String name) { String value = priorityProperties.getProperty(name); if(value == null) { value = resolveProperty(properties.getProperty(name)); } return value; } public Properties resolve(String propertiesResourceLocation) { Properties rawProperties = new Properties(); Properties result = new Properties(); try { Resource resource = context.getResource(propertiesResourceLocation); rawProperties.load(resource.getInputStream()); } catch(IOException e) { throw new TechnicalException(e); } for(String rawPropertyName : rawProperties.stringPropertyNames()) { String overridingValue = getProperty(rawPropertyName); if (StringUtils.isEmpty(overridingValue)) { String rawPropertyValue = rawProperties.getProperty(rawPropertyName); result.setProperty(rawPropertyName, resolveProperty(rawPropertyValue)); } else { result.setProperty(rawPropertyName, overridingValue); } } return result; } private String resolveProperty(String property) { if(property == null) { return null; } for(String rootPropertyName : properties.stringPropertyNames()) { String resolvedProperty= priorityProperties.getProperty(rootPropertyName); if(resolvedProperty==null){ resolvedProperty= properties.getProperty(rootPropertyName); } property = property.replaceAll("\\$\\{" + rootPropertyName + "\\}", resolvedProperty); } return property; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } public void setResources(List<Resource> resources) { setResources(resources, false); } public void setPriorityResources(List<Resource> resources) { setResources(resources, true); } public void addProperties(Properties properties) { mergeProperties(this.properties, properties); } private void setResources(List<Resource> resources, boolean priority) { Properties base = priority ? priorityProperties : properties; try { for(Resource resource : resources) { if(resource != null) { Properties properties = new Properties(); properties.load(resource.getInputStream()); mergeProperties(base, properties); } } } catch (IOException e) { throw new TechnicalException(e); } } private static void mergeProperties(Properties base, Properties mixin) { for(String name : mixin.stringPropertyNames()) { base.setProperty(name, mixin.getProperty(name)); } } }