com.astamuse.asta4d.data.DefaultContextDataFinder.java Source code

Java tutorial

Introduction

Here is the source code for com.astamuse.asta4d.data.DefaultContextDataFinder.java

Source

/*
 * Copyright 2012 astamuse company,Ltd.
 * 
 * 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.astamuse.asta4d.data;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.astamuse.asta4d.Configuration;
import com.astamuse.asta4d.Context;
import com.astamuse.asta4d.data.convertor.DataValueConvertor;
import com.astamuse.asta4d.data.convertor.UnsupportedValueException;
import com.astamuse.asta4d.util.i18n.I18nMessageHelper;

/**
 * A default implementation of {@link ContextDataFinder}. It will search data in a given order (if scope is not specified) and try to apply
 * predefined {@link ContextDataFinder} list to convert data to appropriate type.
 * 
 * @author e-ryu
 * 
 */
public class DefaultContextDataFinder implements ContextDataFinder {

    private final static String ByTypeScope = DefaultContextDataFinder.class.getName() + "#findByType";

    private List<String> dataSearchScopeOrder = getDefaultScopeOrder();

    private final static List<String> getDefaultScopeOrder() {
        List<String> list = new ArrayList<>();
        list.add(Context.SCOPE_ATTR);
        list.add(Context.SCOPE_DEFAULT);
        list.add(Context.SCOPE_GLOBAL);
        return list;
    }

    public List<String> getDataSearchScopeOrder() {
        return dataSearchScopeOrder;
    }

    public void setDataSearchScopeOrder(List<String> dataSearchScopeOrder) {
        this.dataSearchScopeOrder = dataSearchScopeOrder;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public ContextDataHolder findDataInContext(Context context, String scope, String name, Class<?> targetType)
            throws DataOperationException {
        ContextDataHolder dataHolder = findByType(context, scope, name, targetType);

        if (dataHolder != null) {
            return dataHolder;
        }

        if (StringUtils.isEmpty(scope)) {
            dataHolder = findDataByScopeOrder(context, 0, name);
        } else {
            dataHolder = context.getDataHolder(scope, name);
        }

        if (dataHolder == null) {
            return null;
        }

        Object foundData = dataHolder.getValue();
        Object transformedData = null;
        UnsupportedValueException usve = null;

        Class<?> srcType = new TypeInfo(foundData.getClass()).getType();
        if (targetType.isAssignableFrom(srcType)) {
            transformedData = foundData;
        } else if (srcType.isArray() && targetType.isAssignableFrom(srcType.getComponentType())) {
            transformedData = Array.get(foundData, 0);
        } else if (targetType.isArray() && targetType.getComponentType().isAssignableFrom(srcType)) {
            Object array = Array.newInstance(srcType, 1);
            Array.set(array, 0, foundData);
            transformedData = array;
        } else {
            try {
                transformedData = Configuration.getConfiguration().getDataTypeTransformer().transform(srcType,
                        targetType, foundData);
            } catch (UnsupportedValueException ex) {
                usve = ex;
            }
        }
        if (usve == null) {
            dataHolder.setData(dataHolder.getName(), dataHolder.getScope(), foundData, transformedData);
        } else {
            dataHolder.setData(dataHolder.getName(), InjectUtil.ContextDataTypeUnMatchScope, foundData,
                    transformedData);
        }
        return dataHolder;
    }

    @SuppressWarnings("rawtypes")
    private ContextDataHolder findByType(Context context, String scope, String name, Class<?> targetType) {
        if (Context.class.isAssignableFrom(targetType)) {
            return new ContextDataHolder<>(Context.class.getName(), ByTypeScope, context);
        }
        if (I18nMessageHelper.class.isAssignableFrom(targetType)) {
            I18nMessageHelper helper = Configuration.getConfiguration().getI18nMessageHelper();
            return new ContextDataHolder<>(helper.getClass().getName(), ByTypeScope, helper);
        } else {
            return null;
        }
    }

    @SuppressWarnings("rawtypes")
    private ContextDataHolder findDataByScopeOrder(Context context, int scopeIndex, String name) {
        if (scopeIndex >= dataSearchScopeOrder.size()) {
            return null;
        } else {
            String searchScope = dataSearchScopeOrder.get(scopeIndex);
            ContextDataHolder<?> holder = context.getDataHolder(searchScope, name);
            if (holder == null) {
                holder = findDataByScopeOrder(context, scopeIndex + 1, name);
            }
            return holder;
        }
    }

    private Method findConvertMethod(DataValueConvertor<?, ?> convertor) {
        Method[] methods = convertor.getClass().getMethods();
        Method rtnMethod = null;
        for (Method m : methods) {
            if (m.getName().equals("convert") && !m.isBridge()) {
                rtnMethod = m;
                break;
            }
        }
        return rtnMethod;
    }

}