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

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

/*
* 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.api.config.view.PageBeanDescriptor;
import org.apache.myfaces.extensions.cdi.jsf.api.config.view.ViewConfigDescriptor;
import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.spi.EditableViewConfigDescriptor;
import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.spi.LifecycleAwarePageBeanDescriptor;

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 java.io.ObjectInputStream;
import java.io.IOException;

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

/**
* @author Gerhard Petracek
*/
public class DefaultViewConfigDescriptor implements EditableViewConfigDescriptor
{
    private final String viewId;

    private final Class<? extends ViewConfig> viewDefinitionClass;

    private final Page.NavigationMode navigationMode;

    private List<PageBeanDescriptor> pageBeanDescriptors;

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

    private Page.ViewParameterMode viewParameterMode;
    //meta-data
    private List<Annotation> metaDataList;

    private boolean partialViewConfig = false;

    private transient BeanManager beanManager;

    /**
     * Constructor for creating a {@link ViewConfigDescriptor}
     * @param viewId view-id represented by the descriptor
     * @param viewDefinitionClass view-config class
     * @param navigationMode configured navigation-mode
     * @param viewParameterMode configured view-parameter-mode
     * @param accessDecisionVoters configured access-decision-voters
     * @param errorView optional inline error-view
     * @param metaDataList optional meta-data
     */
    public DefaultViewConfigDescriptor(String viewId,
                                       Class<? extends ViewConfig> viewDefinitionClass,
                                       Page.NavigationMode navigationMode,
                                       Page.ViewParameterMode viewParameterMode,
                                       List<Class<? extends AccessDecisionVoter>> accessDecisionVoters,
                                       Class<? extends ViewConfig> errorView,
                                       List<Annotation> metaDataList)
    {
        this.viewId = viewId;
        this.viewDefinitionClass = viewDefinitionClass;
        this.navigationMode = navigationMode;
        this.viewParameterMode = viewParameterMode;

        this.metaDataList = metaDataList;

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

        //noinspection unchecked
        this.accessDecisionVoters = accessDecisionVoters;

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

    /**
     * {@inheritDoc}
     */
    public String getViewId()
    {
        return viewId;
    }

    /**
     * {@inheritDoc}
     */
    public Class<? extends ViewConfig> getViewConfig()
    {
        return viewDefinitionClass;
    }

    /**
     * {@inheritDoc}
     */
    public Page.NavigationMode getNavigationMode()
    {
        return navigationMode;
    }

    /**
     * {@inheritDoc}
     */
    public Page.ViewParameterMode getViewParameterMode()
    {
        return viewParameterMode;
    }

    /**
     * {@inheritDoc}
     */
    public List<PageBeanDescriptor> getPageBeanDescriptors()
    {
        return pageBeanDescriptors;
    }

    /**
     * {@inheritDoc}
     */
    public void invokeInitViewMethods()
    {
        for(PageBeanDescriptor beanEntry : getPageBeanDescriptors())
        {
            if(beanEntry instanceof LifecycleAwarePageBeanDescriptor)
            {
                processCallbacks(beanEntry, ((LifecycleAwarePageBeanDescriptor)beanEntry).getInitViewMethods());
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void invokePrePageActionMethods()
    {
        for(PageBeanDescriptor beanEntry : getPageBeanDescriptors())
        {
            if(beanEntry instanceof LifecycleAwarePageBeanDescriptor)
            {
                processCallbacks(beanEntry, ((LifecycleAwarePageBeanDescriptor)beanEntry).getPrePageActionMethods());
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void invokePreRenderViewMethods()
    {
        for(PageBeanDescriptor beanEntry : getPageBeanDescriptors())
        {
            if(beanEntry instanceof LifecycleAwarePageBeanDescriptor)
            {
                processCallbacks(beanEntry, ((LifecycleAwarePageBeanDescriptor)beanEntry).getPreRenderViewMethods());
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void invokePostRenderViewMethods()
    {
        for(PageBeanDescriptor beanEntry : getPageBeanDescriptors())
        {
            if(beanEntry instanceof LifecycleAwarePageBeanDescriptor)
            {
                processCallbacks(beanEntry, ((LifecycleAwarePageBeanDescriptor)beanEntry).getPostRenderViewMethods());
            }
        }
    }

    private void processCallbacks(PageBeanDescriptor pageBeanDescriptor, List<Method> methodList)
    {
        if(methodList.isEmpty())
        {
            return;
        }

        Object bean = getContextualReferenceByName(getBeanManager(), pageBeanDescriptor.getBeanName(), Object.class);

        if (bean == null)
        {
            //TODO provide a detailed error message in case of a missing bean
            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);
        }
    }

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

    /**
     * {@inheritDoc}
     */
    public Class<? extends ViewConfig> getErrorView()
    {
        return customErrorView;
    }

    /**
     * {@inheritDoc}
     */
    public List<Annotation> getMetaData()
    {
        return metaDataList;
    }

    /**
     * {@inheritDoc}
     */
    public <T extends Annotation> List<T> getMetaData(Class<T> target)
    {
        List<T> result = new ArrayList<T>();

        for(Annotation annotation : this.metaDataList)
        {
            if(target.isAssignableFrom(annotation.annotationType()))
            {
                result.add((T)annotation);
            }
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public void addPageBean(Class pageBeanClass)
    {
        List<PageBeanDescriptor> newList = new ArrayList<PageBeanDescriptor>(this.pageBeanDescriptors);

        PageBeanDescriptor newEntry = new DefaultPageBeanDescriptor(getBeanName(pageBeanClass) , pageBeanClass);

        newList.add(newEntry);

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

    /**
     * {@inheritDoc}
     */
    public void setPartialViewConfig(boolean inlinePageBean)
    {
        this.partialViewConfig = inlinePageBean;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isPartialViewConfig()
    {
        return partialViewConfig;
    }

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

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

        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<PageBeanDescriptor> extractBeanEntries(PageBean.List pageBeanList)
    {
        List<PageBeanDescriptor> result = new ArrayList<PageBeanDescriptor>();
        for(PageBean pageBean : pageBeanList.value())
        {
            result.add(extractBeanEntry(pageBean));
        }
        return result;
    }

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

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

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

        return new DefaultPageBeanDescriptor(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;
    }

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

        ViewConfigDescriptor that = (ViewConfigDescriptor) o;

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

        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode()
    {
        return viewId.hashCode();
    }

    @SuppressWarnings({"UnusedDeclaration"})
    private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException
    {
        objectInputStream.defaultReadObject();
    }
}
TOP

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

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.