com.arondor.common.reflection.parser.spring.BeanPropertyParser.java Source code

Java tutorial

Introduction

Here is the source code for com.arondor.common.reflection.parser.spring.BeanPropertyParser.java

Source

/*
 *  Copyright 2013, Arondor
 *
 *  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.
 */
package com.arondor.common.reflection.parser.spring;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.context.expression.BeanExpressionContextAccessor;
import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.context.expression.EnvironmentAccessor;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.arondor.common.reflection.api.hash.HashHelper;
import com.arondor.common.reflection.model.config.ElementConfiguration;
import com.arondor.common.reflection.model.config.ListConfiguration;
import com.arondor.common.reflection.model.config.MapConfiguration;
import com.arondor.common.reflection.model.config.ObjectConfiguration;
import com.arondor.common.reflection.model.config.ObjectConfigurationFactory;
import com.arondor.common.reflection.model.config.PrimitiveConfiguration;
import com.arondor.common.reflection.model.config.ReferenceConfiguration;

abstract class BeanPropertyParser {
    private static final Logger LOGGER = Logger.getLogger(BeanPropertyParser.class);

    private final HashHelper hashHelper;

    private final ObjectConfigurationFactory objectConfigurationFactory;

    private boolean enableSPEL = true;

    public BeanPropertyParser(HashHelper hashHelper, ObjectConfigurationFactory objectConfigurationFactory) {
        this.hashHelper = hashHelper;
        this.objectConfigurationFactory = objectConfigurationFactory;
    }

    public ElementConfiguration parseProperty(Object value) {
        LOGGER.debug("value : " + value);
        if (value instanceof TypedStringValue) {
            TypedStringValue stringValue = (TypedStringValue) value;
            if (stringValue.getTargetTypeName() != null) {
                return getEnumObjectConfiguration(stringValue);
            } else {
                PrimitiveConfiguration primitiveConfiguration = objectConfigurationFactory
                        .createPrimitiveConfiguration();
                if (useSPEL(stringValue)) {
                    ExpressionParser parser = new SpelExpressionParser();
                    String expAsStringWithToken = stringValue.getValue().trim();
                    String expAsString = expAsStringWithToken.substring(2, expAsStringWithToken.length() - 1)
                            .trim();
                    LOGGER.trace("This property is a SPEL expression: " + expAsString);

                    // String regex = "systemProperties\\['([^\\s]+)'\\]";

                    Expression exp = parser.parseExpression(expAsString);
                    StandardEvaluationContext sec = null;
                    if (sec == null) {
                        sec = new StandardEvaluationContext();
                        sec.addPropertyAccessor(new EnvironmentAccessor());
                        sec.addPropertyAccessor(new BeanExpressionContextAccessor());
                        sec.addPropertyAccessor(new BeanFactoryAccessor());
                        sec.addPropertyAccessor(new MapAccessor());
                    }
                    primitiveConfiguration.setValue(String.valueOf(exp.getValue()));
                } else {
                    LOGGER.trace("This property is NOT a SPEL expression: " + stringValue.getValue());
                    primitiveConfiguration.setValue(stringValue.getValue());
                }
                return primitiveConfiguration;
            }
        } else if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference beanReference = (RuntimeBeanReference) value;
            ReferenceConfiguration referenceConfiguration = objectConfigurationFactory
                    .createReferenceConfiguration();
            referenceConfiguration.setReferenceName(beanReference.getBeanName());
            return referenceConfiguration;
        } else if (value instanceof ManagedList<?>) {
            return parseValueList((ManagedList<?>) value);
        } else if (value instanceof ManagedMap<?, ?>) {
            return parseValueMap((ManagedMap<?, ?>) value);
        } else if (value instanceof BeanDefinitionHolder) {
            BeanDefinitionHolder beanDefinitionHolder = (BeanDefinitionHolder) value;
            return parseBeanDefinition(beanDefinitionHolder.getBeanDefinition());
        } else {
            throw new UnsupportedOperationException("The type of property value is not suppported : " + value
                    + " (class : " + value.getClass().getName() + ")");
        }
    }

    private boolean useSPEL(TypedStringValue stringValue) {
        if (!enableSPEL || stringValue == null || stringValue.getValue() == null) {
            return false;
        }
        String trimmedValue = stringValue.getValue().trim();
        return trimmedValue.startsWith("#{") && trimmedValue.endsWith("}");
    }

    private ObjectConfiguration getEnumObjectConfiguration(TypedStringValue stringValue) {
        ObjectConfiguration enumObjectConfiguration = objectConfigurationFactory.createObjectConfiguration();
        enumObjectConfiguration.setClassName(hashHelper.hashClassName(stringValue.getTargetTypeName()));
        enumObjectConfiguration.setConstructorArguments(new ArrayList<ElementConfiguration>());

        PrimitiveConfiguration enumFieldConfiguration = objectConfigurationFactory
                .createPrimitiveConfiguration(stringValue.getValue());
        enumObjectConfiguration.getConstructorArguments().add(enumFieldConfiguration);
        return enumObjectConfiguration;
    }

    private ElementConfiguration parseValueList(ManagedList<?> value) {
        return parseBeanList(value);
    }

    private ElementConfiguration parseValueMap(ManagedMap<?, ?> value) {
        MapConfiguration mapConfiguration = objectConfigurationFactory.createMapConfiguration();
        mapConfiguration.setMapConfiguration(new HashMap<ElementConfiguration, ElementConfiguration>());

        for (Entry<?, ?> entry : value.entrySet()) {
            LOGGER.debug("entry key=" + entry.getKey() + ", value=" + entry.getValue());
            ElementConfiguration keyConfiguration = parseBeanObject(entry.getKey());
            ElementConfiguration valueConfiguration = parseBeanObject(entry.getValue());
            mapConfiguration.getMapConfiguration().put(keyConfiguration, valueConfiguration);
        }

        return mapConfiguration;
    }

    // private ElementConfiguration parseFieldList(ManagedList<?> value)
    // {
    // @SuppressWarnings("unchecked")
    // ManagedList<TypedStringValue> stringValueList =
    // (ManagedList<TypedStringValue>) value;
    //
    // ListConfiguration listConfiguration =
    // objectConfigurationFactory.createListConfiguration();
    // listConfiguration.setListConfiguration(new
    // ArrayList<ElementConfiguration>());
    //
    // for (TypedStringValue stringValue : stringValueList)
    // {
    // ElementConfiguration primitiveConfiguration = objectConfigurationFactory
    // .createPrimitiveConfiguration(stringValue.getValue());
    // listConfiguration.getListConfiguration().add(primitiveConfiguration);
    // }
    // return listConfiguration;
    // }

    private ElementConfiguration parseBeanObject(Object item) {
        if (item instanceof TypedStringValue) {
            TypedStringValue stringValue = (TypedStringValue) item;
            ElementConfiguration primitiveConfiguration = objectConfigurationFactory
                    .createPrimitiveConfiguration(stringValue.getValue());
            return primitiveConfiguration;
        } else if (item instanceof RuntimeBeanReference) {
            RuntimeBeanReference runtimeBeanReference = (RuntimeBeanReference) item;
            // return parseBeanDefinition(runtimeBeanReference.getBeanName());
            ReferenceConfiguration reference = objectConfigurationFactory.createReferenceConfiguration();
            reference.setReferenceName(runtimeBeanReference.getBeanName());
            return reference;
        } else if (item instanceof BeanDefinitionHolder) {
            BeanDefinitionHolder beanDefinitionHolder = (BeanDefinitionHolder) item;
            return parseBeanDefinition(beanDefinitionHolder.getBeanDefinition());
        } else {
            throw new IllegalArgumentException("Not supported : item class " + item.getClass().getName());
        }

    }

    private ElementConfiguration parseBeanList(ManagedList<?> managedList) {
        ListConfiguration listConfiguration = objectConfigurationFactory.createListConfiguration();
        listConfiguration.setListConfiguration(new ArrayList<ElementConfiguration>());

        for (Object item : managedList) {
            ElementConfiguration elementConfiguration = parseBeanObject(item);
            listConfiguration.getListConfiguration().add(elementConfiguration);
        }
        return listConfiguration;
    }

    public abstract ObjectConfiguration parseBeanDefinition(String beanDefinitionName);

    public abstract ObjectConfiguration parseBeanDefinition(BeanDefinition beanDefinition);

    public boolean isEnableSPEL() {
        return enableSPEL;
    }

    public void setEnableSPEL(boolean enableSPEL) {
        this.enableSPEL = enableSPEL;
    }
}