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

org.raml.parser.builder.DefaultTupleBuilder Maven / Gradle / Ivy

There is a newer version: 0.8.40
Show newest version
/*
 * Copyright 2016 (c) MuleSoft, Inc.
 *
 * 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 org.raml.parser.builder;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.raml.parser.annotation.Key;
import org.raml.parser.annotation.Mapping;
import org.raml.parser.annotation.Parent;
import org.raml.parser.annotation.Scalar;
import org.raml.parser.annotation.Sequence;
import org.raml.parser.resolver.DefaultTupleHandler;
import org.raml.parser.resolver.TupleHandler;
import org.raml.parser.utils.ReflectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.apache.commons.beanutils.SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS;

public class DefaultTupleBuilder implements TupleBuilder
{
    private BeanUtilsBean beanUtilsBean;
    private Map> builders;
    private NodeBuilder parent;
    private TupleHandler handler;

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    public DefaultTupleBuilder(TupleHandler tupleHandler)
    {
        builders = new HashMap>();
        this.setHandler(tupleHandler);
        beanUtilsBean = new BeanUtilsBean();
        beanUtilsBean.getPropertyUtils().addBeanIntrospector(SUPPRESS_CLASS);
    }

    @Override
    public NodeBuilder getBuilderForTuple(NodeTuple tuple)
    {
        if (getBuilders() == null || getBuilders().isEmpty())
        {
            return new DefaultTupleBuilder(new DefaultTupleHandler());
        }
        for (TupleBuilder tupleBuilder : getBuilders().values())
        {
            if (tupleBuilder.getHandler().handles(tuple))
            {
                return tupleBuilder;
            }
        }
        throw new RuntimeException("Builder not found for " + tuple);
    }

    protected Map> getBuilders()
    {
        return builders;
    }

    public Collection> getChildrenTupleBuilders()
    {
        return getBuilders().values();
    }


    @Override
    public Object buildValue(Object parent, V node)
    {
        return parent;
    }

    public void setHandler(TupleHandler handler)
    {
        this.handler = handler;
    }

    @Override
    public TupleHandler getHandler()
    {
        return handler;
    }

    @Override
    public void buildKey(Object parent, K tuple)
    {

    }

    @Override
    public void setParentNodeBuilder(NodeBuilder parentBuilder)
    {
        parent = parentBuilder;
    }

    @Override
    public void setChildrenTupleBuilders(Map> nestedBuilders)
    {
        builders = nestedBuilders;
    }


    public void addBuildersFor(Class documentClass)
    {
        new TupleBuilderFactory().addBuildersTo(documentClass, this);
    }


    public NodeBuilder getParent()
    {
        return parent;
    }

    //TODO rethink location
    protected String unalias(Object pojo, String fieldName)
    {
        List declaredFields = ReflectionUtils.getInheritedFields(pojo.getClass());
        for (Field declaredField : declaredFields)
        {
            Scalar scalar = declaredField.getAnnotation(Scalar.class);
            Mapping mapping = declaredField.getAnnotation(Mapping.class);
            Sequence sequence = declaredField.getAnnotation(Sequence.class);
            if ((scalar != null && scalar.alias() != null && scalar.alias().equals(fieldName)) ||
                (mapping != null && mapping.alias() != null && mapping.alias().equals(fieldName)) ||
                (sequence != null && sequence.alias() != null && sequence.alias().equals(fieldName)))
            {
                return declaredField.getName();
            }
        }
        return fieldName;
    }

    protected void processPojoAnnotations(Object pojo, Object keyFieldName, Object parent)
    {
        List declaredFields = ReflectionUtils.getInheritedFields(pojo.getClass());
        for (Field declaredField : declaredFields)
        {
            Key keyAnnotation = declaredField.getAnnotation(Key.class);
            Parent parentAnnotation = declaredField.getAnnotation(Parent.class);
            if (keyAnnotation != null)
            {
                ReflectionUtils.setProperty(pojo, declaredField.getName(), keyFieldName);
            }
            if (parentAnnotation != null)
            {
                Object value = parent;
                if (!parentAnnotation.property().isEmpty())
                {
                    try
                    {
                        value = beanUtilsBean.getPropertyUtils().getProperty(parent, parentAnnotation.property());
                    }
                    catch (IllegalAccessException e)
                    {
                        throw new RuntimeException(e);
                    }
                    catch (InvocationTargetException e)
                    {
                        throw new RuntimeException(e);
                    }
                    catch (NoSuchMethodException e)
                    {
                        throw new RuntimeException(e);
                    }
                }
                if (declaredField.getType().isAssignableFrom(value.getClass()))
                {
                    ReflectionUtils.setProperty(pojo, declaredField.getName(), value);
                }
                else
                {
                    logger.debug(String.format("parent reference field '%s' could not be set with %s onto %s",
                                              declaredField.getName(), value.getClass(), pojo.getClass()));
                }
            }
        }
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy