org.smallmind.nutsnbolts.spring.PropertyPlaceholderConfigurer Maven / Gradle / Ivy
/*
* Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 David Berkman
*
* This file is part of the SmallMind Code Project.
*
* The SmallMind Code Project is free software, you can redistribute
* it and/or modify it under either, at your discretion...
*
* 1) The terms of GNU Affero General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* ...or...
*
* 2) The terms of the Apache License, Version 2.0.
*
* The SmallMind Code Project 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
* General Public License or Apache License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and the Apache License along with the SmallMind Code Project. If not, see
* or .
*
* Additional permission under the GNU Affero GPL version 3 section 7
* ------------------------------------------------------------------
* If you modify this Program, or any covered work, by linking or
* combining it with other code, such other code is not for that reason
* alone subject to any of the requirements of the GNU Affero GPL
* version 3.
*/
package org.smallmind.nutsnbolts.spring;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import org.smallmind.nutsnbolts.property.PropertyExpander;
import org.smallmind.nutsnbolts.property.PropertyExpanderException;
import org.smallmind.nutsnbolts.resource.Resource;
import org.smallmind.nutsnbolts.resource.ResourceException;
import org.smallmind.nutsnbolts.resource.ResourceParser;
import org.smallmind.nutsnbolts.resource.ResourceTypeResourceFactory;
import org.smallmind.nutsnbolts.spring.property.PropertyEntry;
import org.smallmind.nutsnbolts.spring.property.PropertyFileType;
import org.smallmind.nutsnbolts.spring.property.PropertyHandler;
import org.smallmind.nutsnbolts.util.DotNotationComparator;
import org.smallmind.nutsnbolts.util.DotNotationException;
import org.smallmind.nutsnbolts.util.SystemPropertyMode;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.core.PriorityOrdered;
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor, BeanFactoryAware, BeanNameAware, PriorityOrdered {
private final TreeMap debugMap = new TreeMap<>(new DotNotationComparator());
private final List locations = new LinkedList<>();
private BeanFactory beanFactory;
private KeyDebugger keyDebugger;
private String beanName;
private SystemPropertyMode systemPropertyMode = SystemPropertyMode.FALLBACK;
private boolean ignoreResourceNotFound = false;
private boolean ignoreUnresolvableProperties = false;
private boolean searchSystemEnvironment = true;
private int order;
public SortedMap getDebugMap () {
return Collections.unmodifiableSortedMap(debugMap);
}
public void setBeanFactory (BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void setBeanName (String beanName) {
this.beanName = beanName;
}
@Override
public int getOrder () {
return order;
}
public void setOrder (int order) {
this.order = order;
}
public void setSystemPropertyMode (SystemPropertyMode systemPropertyMode) {
this.systemPropertyMode = systemPropertyMode;
}
public void setIgnoreResourceNotFound (boolean ignoreResourceNotFound) {
this.ignoreResourceNotFound = ignoreResourceNotFound;
}
public void setIgnoreUnresolvableProperties (boolean ignoreUnresolvableProperties) {
this.ignoreUnresolvableProperties = ignoreUnresolvableProperties;
}
public void setSearchSystemEnvironment (boolean searchSystemEnvironment) {
this.searchSystemEnvironment = searchSystemEnvironment;
}
public void setLocations (List locations) {
this.locations.addAll(locations);
}
public void setDebugKeys (String[] debugPatterns)
throws DotNotationException {
keyDebugger = new KeyDebugger(debugPatterns);
}
@Override
public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactoryToProcess)
throws BeansException {
PropertyPlaceholderStringValueResolver valueResolver;
Map propertyMap = new HashMap<>();
ResourceParser resourceParser;
PropertyExpander locationExpander;
BeanDefinitionVisitor beanDefinitionVisitor;
resourceParser = new ResourceParser(new ResourceTypeResourceFactory());
try {
locationExpander = new PropertyExpander(true, SystemPropertyMode.OVERRIDE, true);
} catch (PropertyExpanderException propertyExpanderException) {
throw new RuntimeBeansException(propertyExpanderException);
}
for (String beanName : beanFactoryToProcess.getBeanDefinitionNames()) {
BeanDefinition beanDefinition;
if (Objects.equals((beanDefinition = beanFactoryToProcess.getBeanDefinition(beanName)).getBeanClassName(), PropertyConfiguration.class.getName())) {
PropertyValue propertyValue;
if ((propertyValue = beanDefinition.getPropertyValues().getPropertyValue("locations")) == null) {
throw new BeanDefinitionValidationException("The property configuration bean(" + beanName + ") is missing its 'locations' property");
} else {
Object value;
if ((value = propertyValue.getValue()) == null) {
throw new BeanDefinitionValidationException("The property configuration bean(" + beanName + ") is missing its 'locations' property");
} else if (value instanceof TypedStringValue) {
String additionalLocation = ((TypedStringValue)value).getValue();
if (!locations.contains(additionalLocation)) {
locations.add(additionalLocation);
}
} else if (value instanceof ManagedList) {
for (Object childValue : (ManagedList>)value) {
if (childValue instanceof TypedStringValue) {
String additionalLocation = ((TypedStringValue)childValue).getValue();
if (!locations.contains(additionalLocation)) {
locations.add(additionalLocation);
}
} else {
throw new BeanDefinitionValidationException("The property configuration bean(" + beanName + ") is missing its 'locations' property");
}
}
} else {
throw new BeanDefinitionValidationException("The 'locations' property for the bean(" + beanName + ") could not be parsed");
}
}
}
}
System.out.println("---------------- Property Loading ----------------");
for (String location : locations) {
extractProperties(resourceParser, locationExpander, propertyMap, location);
}
System.out.println("--------------------------------------------------");
SpringPropertyAccessorManager.register(new SpringPropertyAccessor(valueResolver = new PropertyPlaceholderStringValueResolver(propertyMap, ignoreUnresolvableProperties, systemPropertyMode, searchSystemEnvironment)));
if ((keyDebugger != null) && keyDebugger.willDebug()) {
for (Map.Entry propertyEntry : propertyMap.entrySet()) {
if (keyDebugger.matches(propertyEntry.getKey())) {
Object value;
debugMap.put(propertyEntry.getKey(), valueResolver.resolveStringValue(((value = propertyEntry.getValue()) == null) ? "" : value.toString()));
}
}
System.out.println("---------------- Config Properties ---------------");
for (Map.Entry debugEntry : debugMap.entrySet()) {
System.out.println("[" + debugEntry.getKey() + "=" + debugEntry.getValue() + "]");
}
System.out.println("--------------------------------------------------");
}
beanDefinitionVisitor = new BeanDefinitionVisitor(valueResolver);
for (String beanName : beanFactoryToProcess.getBeanDefinitionNames()) {
if ((!(beanName.equals(this.beanName)) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition beanDefinition = beanFactoryToProcess.getBeanDefinition(beanName);
try {
beanDefinitionVisitor.visitBeanDefinition(beanDefinition);
} catch (BeanDefinitionStoreException beanDefinitionStoreException) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, beanDefinitionStoreException.getMessage());
}
}
}
beanFactoryToProcess.resolveAliases(valueResolver);
}
private void extractProperties (ResourceParser resourceParser, PropertyExpander locationExpander, Map propertyMap, String location) {
Resource locationResource;
InputStream inputStream;
try {
locationResource = resourceParser.parseResource(locationExpander.expand(location));
if ((inputStream = locationResource.getInputStream()) == null) {
throw new ResourceException("No stream available for resource(" + locationResource + ")");
} else {
PropertyHandler> propertyHandler;
PropertyFileType propertyFileType;
int lastDotPos;
if ((lastDotPos = locationResource.getPath().lastIndexOf('.')) >= 0) {
if ((propertyFileType = PropertyFileType.forExtension(locationResource.getPath().substring(lastDotPos + 1))) == null) {
propertyFileType = PropertyFileType.PROPERTIES;
}
} else {
propertyFileType = PropertyFileType.PROPERTIES;
}
propertyHandler = propertyFileType.getPropertyHandler(inputStream);
System.out.println("[" + propertyFileType.name() + ":" + locationResource.getPath() + "]");
for (PropertyEntry propertyEntry : propertyHandler) {
propertyMap.put(propertyEntry.getKey(), propertyEntry.getValue());
}
}
} catch (Exception exception) {
if ((!ignoreResourceNotFound) || (!(exception instanceof ResourceException))) {
throw new RuntimeBeansException(exception);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy