Package org.apache.myfaces.extensions.cdi.jsf.impl.config.view

Source Code of org.apache.myfaces.extensions.cdi.jsf.impl.config.view.DefaultViewConfigEntry

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.myfaces.extensions.cdi.jsf.impl.config.view;

import org.apache.myfaces.extensions.cdi.core.api.config.view.DefaultErrorView;
import org.apache.myfaces.extensions.cdi.core.api.config.view.ViewConfig;
import org.apache.myfaces.extensions.cdi.core.api.provider.BeanManagerProvider;
import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoter;
import org.apache.myfaces.extensions.cdi.jsf.api.config.view.Page;
import org.apache.myfaces.extensions.cdi.jsf.api.config.view.PageBean;
import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.spi.PageBeanConfigEntry;
import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.spi.ViewConfigEntry;

import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Named;
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils.getOrCreateScopedInstanceOfBeanByName;

/**
* @author Gerhard Petracek
*/
public class DefaultViewConfigEntry implements ViewConfigEntry
{
    private static final long serialVersionUID = 4707048794409336152L;

    private final String viewId;

    private final Class<? extends ViewConfig> viewDefinitionClass;

    private final Page.NavigationMode navigationMode;

    private List<PageBeanConfigEntry> beanDefinition;

    //security
    private final List<Class<? extends AccessDecisionVoter>> accessDecisionVoters;
    private final Class<? extends ViewConfig> customErrorView;

    private Page.ViewParameter viewParameter;
    //meta-data
    private List<Annotation> metaDataList;

    private boolean simpleEntryMode = false;

    private BeanManager beanManager;

    public DefaultViewConfigEntry(String viewId,
                                  Class<? extends ViewConfig> viewDefinitionClass,
                                  Page.NavigationMode navigationMode,
                                  Page.ViewParameter viewParameter,
                                  List<Class<? extends AccessDecisionVoter>> accessDecisionVoters,
                                  Class<? extends ViewConfig> errorView,
                                  List<Annotation> metaDataList)
    {
        this.viewId = viewId;
        this.viewDefinitionClass = viewDefinitionClass;
        this.navigationMode = navigationMode;
        this.viewParameter = viewParameter;

        this.metaDataList = metaDataList;

        beanDefinition = Collections.unmodifiableList(findPageBeanDefinitions(viewDefinitionClass));
        //TODO validate view-id

        //noinspection unchecked
        this.accessDecisionVoters = accessDecisionVoters;

        if(errorView != null)
        {
            this.customErrorView = errorView;
        }
        else
        {
            this.customErrorView = DefaultErrorView.class;
        }
    }

    public String getViewId()
    {
        return viewId;
    }

    public Class<? extends ViewConfig> getViewDefinitionClass()
    {
        return viewDefinitionClass;
    }

    public Page.NavigationMode getNavigationMode()
    {
        return navigationMode;
    }

    public Page.ViewParameter getViewParameter()
    {
        return viewParameter;
    }

    public List<PageBeanConfigEntry> getPageBeanDefinitions()
    {
        return beanDefinition;
    }

    public void invokeInitViewMethods()
    {
        for(PageBeanConfigEntry beanEntry : getPageBeanDefinitions())
        {
            processCallbacks(beanEntry, beanEntry.getInitViewMethods());
        }
    }

    public void invokePrePageActionMethods()
    {
        for(PageBeanConfigEntry beanEntry : getPageBeanDefinitions())
        {
            processCallbacks(beanEntry, beanEntry.getPrePageActionMethods());
        }
    }

    public void invokePreRenderViewMethods()
    {
        for(PageBeanConfigEntry beanEntry : getPageBeanDefinitions())
        {
            processCallbacks(beanEntry, beanEntry.getPreRenderViewMethods());
        }
    }

    public void invokePostRenderViewMethods()
    {
        for(PageBeanConfigEntry beanEntry : getPageBeanDefinitions())
        {
            processCallbacks(beanEntry, beanEntry.getPostRenderViewMethods());
        }
    }

    private void processCallbacks(PageBeanConfigEntry beanEntry, List<Method> methodList)
    {
        Object bean;
        if (!methodList.isEmpty())
        {
            //TODO provide a detailed error message in case of a missing bean
            bean = getOrCreateScopedInstanceOfBeanByName(getBeanManager(), beanEntry.getBeanName(), Object.class);

            if (bean == null)
            {
                return;
            }

            for (Method callbackMethod : methodList)
            {
                invokeMethod(bean, callbackMethod);
            }
        }
    }

    private void invokeMethod(Object bean, Method preProcessMethod)
    {
        try
        {
            preProcessMethod.setAccessible(true);
            preProcessMethod.invoke(bean);
        }
        catch (Exception e)
        {
            throw new IllegalStateException(e);
        }
    }

    public List<Class<? extends AccessDecisionVoter>> getAccessDecisionVoters()
    {
        return Collections.unmodifiableList(this.accessDecisionVoters);
    }

    public Class<? extends ViewConfig> getErrorView()
    {
        return customErrorView;
    }

    public List<Annotation> getMetaData()
    {
        return metaDataList;
    }

    public synchronized void addMetaData(Annotation annotation)
    {
        this.metaDataList.add(annotation);
    }

    public synchronized List<Annotation> resetMetaData()
    {
        try
        {
            return new ArrayList<Annotation>(this.metaDataList);
        }
        finally
        {
            this.metaDataList.clear();
        }
    }

    public void addPageBean(Class pageBeanClass)
    {
        List<PageBeanConfigEntry> newList = new ArrayList<PageBeanConfigEntry>(this.beanDefinition);

        PageBeanConfigEntry newEntry = new DefaultPageBeanConfigEntry(getBeanName(pageBeanClass) , pageBeanClass);

        newList.add(newEntry);

        this.beanDefinition = Collections.unmodifiableList(newList);
    }

    void activateSimpleEntryMode()
    {
        this.simpleEntryMode = true;
    }

    boolean isSimpleEntryMode()
    {
        return simpleEntryMode;
    }

    private List<PageBeanConfigEntry> findPageBeanDefinitions(Class<? extends ViewConfig> viewDefinitionClass)
    {
        if(!viewDefinitionClass.isAnnotationPresent(PageBean.class) &&
                !viewDefinitionClass.isAnnotationPresent(PageBean.List.class))
        {
            return Collections.emptyList();
        }

        List<PageBeanConfigEntry> result = new ArrayList<PageBeanConfigEntry>();

        if(viewDefinitionClass.isAnnotationPresent(PageBean.class))
        {
            result.add(extractBeanEntry(viewDefinitionClass.getAnnotation(PageBean.class)));
        }

        if(viewDefinitionClass.isAnnotationPresent(PageBean.List.class))
        {
            result.addAll(extractBeanEntries(viewDefinitionClass.getAnnotation(PageBean.List.class)));
        }

        return result;
    }

    private List<PageBeanConfigEntry> extractBeanEntries(PageBean.List pageBeanList)
    {
        List<PageBeanConfigEntry> result = new ArrayList<PageBeanConfigEntry>();
        for(PageBean pageBean : pageBeanList.value())
        {
            result.add(extractBeanEntry(pageBean));
        }
        return result;
    }

    private PageBeanConfigEntry extractBeanEntry(PageBean pageBean)
    {
        if(!"".equals(pageBean.name()))
        {
            return new DefaultPageBeanConfigEntry(pageBean.name(), pageBean.value());
        }

        Class<?> pageBeanClass = pageBean.value();
        String pageBeanName = null;

        //TODO allow indirect usage of @Named
        pageBeanName = getBeanName(pageBeanClass);

        return new DefaultPageBeanConfigEntry(pageBeanName, pageBeanClass);
    }

    private String getBeanName(Class<?> pageBeanClass)
    {
        if(pageBeanClass.isAnnotationPresent(Named.class))
        {
            String beanName = pageBeanClass.getAnnotation(Named.class).value();

            if(!"".equals(beanName))
            {
                return beanName;
            }
        }

        return Introspector.decapitalize(pageBeanClass.getSimpleName());
    }

    private BeanManager getBeanManager()
    {
        if(this.beanManager == null)
        {
            this.beanManager = BeanManagerProvider.getInstance().getBeanManager();
        }

        return this.beanManager;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
        {
            return true;
        }
        if (!(o instanceof ViewConfigEntry))
        {
            return false;
        }

        ViewConfigEntry that = (ViewConfigEntry) o;

        if (!viewId.equals(that.getViewId()))
        {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode()
    {
        return viewId.hashCode();
    }
}
TOP

Related Classes of org.apache.myfaces.extensions.cdi.jsf.impl.config.view.DefaultViewConfigEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.