All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ff4j.spring.placeholder.PropertiesPlaceHolderBeanDefinitionVisitor Maven / Gradle / Ivy

package org.ff4j.spring.placeholder;

/*
 * #%L
 * ff4j-aop
 * %%
 * Copyright (C) 2013 - 2015 Ff4J
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */


import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.ff4j.FF4j;
import org.ff4j.core.Feature;
import org.ff4j.exception.FeatureNotFoundException;
import org.ff4j.exception.PropertyNotFoundException;
import org.ff4j.property.Property;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;

/**
 * Pattern Bean Visitor.
 *
 * @author Cedrick LUNVEN
 */
public class PropertiesPlaceHolderBeanDefinitionVisitor extends BeanDefinitionVisitor {
    
    /** Static commons-log LOG for this class. * */
    private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesPlaceHolderBeanDefinitionVisitor.class);
    
    /** Properties Map from store **/
    private Map> propertiesMap = new HashMap>();
    
    /** Properties Map from store **/
    private Map featuresMap = new HashMap();
    
    /** Prefix to every registry stored adress. * */
    public static final String PLACEHOLDER_PROPERTY_PREFIX = "@ff4jProperty{";
    
    /** Prefix to every registry stored adress. * */
    public static final String PLACEHOLDER_FEATURE_PREFIX = "@ff4jFeature{";

    /** Prefix to every registry stored adress. * */
    public static final String PLACEHOLDER_SUFFIX = "}";
    
    /**
     * Instanciate visitor.
     * @param serviceMap
     *      parameter service map
     */
    public PropertiesPlaceHolderBeanDefinitionVisitor(FF4j ff4j) {
        if (ff4j == null) {
           throw new IllegalArgumentException("Cannot initialize placeholding 'ff4j' is null");
        }       
        this.propertiesMap = ff4j.getProperties();
        this.featuresMap   = ff4j.getFeatures();
    }
    
    /** {@inheritDoc} */
    protected String resolveStringValue(String strVal) throws BeansException {
        return parseStringValue(strVal, propertiesMap, featuresMap, new HashSet());
    }
    
    /**
     * Parsing value to handle
     * @param strVal
     * @param uriMap
     * @param visitedPlaceholders
     * @return
     * @throws BeanDefinitionStoreException
     */
    protected String parseStringValue(String strVal, Map> propertiesMap, Map featureMap, Set visitedPlaceholders) 
    throws BeanDefinitionStoreException {
        StringBuilder builder = new StringBuilder(strVal);
        
        // @ff4jProperty{}
        int startIndex = strVal.indexOf(PLACEHOLDER_PROPERTY_PREFIX);
        while (startIndex != -1) {
            int endIndex = builder.toString().indexOf(PLACEHOLDER_SUFFIX, startIndex + PLACEHOLDER_PROPERTY_PREFIX.length());
            if (endIndex != -1) {
                String placeholder = builder.substring(startIndex + PLACEHOLDER_PROPERTY_PREFIX.length(), endIndex);
                if (!visitedPlaceholders.add(placeholder)) {
                    throw new BeanDefinitionStoreException("Circular placeholder reference '" + placeholder + "' in property definitions");
                }
                if (propertiesMap==null || !propertiesMap.containsKey(placeholder)) {
                    throw new PropertyNotFoundException(
                            PLACEHOLDER_PROPERTY_PREFIX + ": Cannot perform placeholding on " + placeholder);
                }
                String propVal = propertiesMap.get(placeholder).asString();
                if (propVal != null) {
                    propVal = parseStringValue(propVal, propertiesMap, featureMap, visitedPlaceholders);
                    builder.replace(startIndex, endIndex + PLACEHOLDER_SUFFIX.length(), propVal);
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Resolved placeholder '{}' to value '{}'", placeholder, propVal);
                    }
                    startIndex = builder.toString().indexOf(PLACEHOLDER_PROPERTY_PREFIX, startIndex + propVal.length());
                } else {
                    throw new BeanDefinitionStoreException("Could not resolve placeholder '" + placeholder + "'");
                }
                visitedPlaceholders.remove(placeholder);
            } else {
                startIndex = -1;
            }
        }
        
        // @ff4jFeature{}
        startIndex = strVal.indexOf(PLACEHOLDER_FEATURE_PREFIX);
        while (startIndex != -1) {
            int endIndex = builder.toString().indexOf(PLACEHOLDER_SUFFIX, startIndex + PLACEHOLDER_FEATURE_PREFIX.length());
            if (endIndex != -1) {
                String placeholder = builder.substring(startIndex + PLACEHOLDER_FEATURE_PREFIX.length(), endIndex);
                if (!visitedPlaceholders.add(placeholder)) {
                    throw new BeanDefinitionStoreException("Circular placeholder reference '" + placeholder + "' in property definitions");
                }
                if (featureMap==null || !featureMap.containsKey(placeholder)) {
                    throw new FeatureNotFoundException(
                            PLACEHOLDER_FEATURE_PREFIX + ": Cannot perform placeholding on " + placeholder);
                }
                String propVal = String.valueOf(featureMap.get(placeholder).isEnable());
                if (propVal != null) {
                    propVal = parseStringValue(propVal, propertiesMap, featureMap, visitedPlaceholders);
                    builder.replace(startIndex, endIndex + PLACEHOLDER_FEATURE_PREFIX.length(), propVal);
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Resolved placeholder '{}' to value '{}'", placeholder, propVal);
                    }
                    startIndex = builder.toString().indexOf(PLACEHOLDER_FEATURE_PREFIX, startIndex + propVal.length());
                } else {
                    throw new BeanDefinitionStoreException("Could not resolve placeholder '" + placeholder + "'");
                }
                visitedPlaceholders.remove(placeholder);
            } else {
                startIndex = -1;
            }
        }
        
        return builder.toString();
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy