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

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

/*
* 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.ViewConfig;
import org.apache.myfaces.extensions.cdi.core.api.config.view.View;
import org.apache.myfaces.extensions.cdi.core.impl.util.ClassDeactivation;
import org.apache.myfaces.extensions.cdi.core.api.Deactivatable;
import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
import org.apache.myfaces.extensions.cdi.jsf.api.config.view.Page;
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 org.apache.myfaces.extensions.cdi.jsf.impl.config.view.spi.ViewConfigExtractor;
import org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.ViewControllerInterceptor;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.AnnotatedType;
import java.lang.reflect.Modifier;

/**
* @author Gerhard Petracek
*/
@SuppressWarnings({"UnusedDeclaration"})
public class ViewConfigExtension implements Extension, Deactivatable
{
    private static final String VIEW_CONFIG_EXTRACTOR_PROPERTY_NAME =
            "org.apache.myfaces.extensions.cdi.ViewConfigExtractor";

    private static final String VIEW_CONFIG_EXTRACTOR_JNDI_NAME =
            "java:comp/env/myfaces-codi/ViewConfigExtractor";

    public void processPageDefinitions(@Observes ProcessAnnotatedType processAnnotatedType)
    {
        if(!isActivated())
        {
            return;
        }

        if (processAnnotatedType.getAnnotatedType().isAnnotationPresent(Page.class))
        {
            addPageDefinition(processAnnotatedType.getAnnotatedType().getJavaClass());
            processAnnotatedType.veto();
        }

        if (processAnnotatedType.getAnnotatedType().isAnnotationPresent(View.class) &&
                !processAnnotatedType.getAnnotatedType().getJavaClass().equals(ViewControllerInterceptor.class))
        {
            addPageBean(processAnnotatedType.getAnnotatedType());

            //noinspection unchecked
            processAnnotatedType.setAnnotatedType(
                                new ViewControllerWrapper(processAnnotatedType.getAnnotatedType()));
        }
    }

    protected void addPageDefinition(Class pageDefinitionClass)
    {
        ViewConfigEntry newEntry = createViewConfigEntry(pageDefinitionClass);

        if(newEntry != null)
        {
            ViewConfigEntry existingEntry = ViewConfigCache.getViewDefinition(newEntry.getViewDefinitionClass());

            //TODO introduce an SPI with a better name
            if(/*viewConfigEntry != null*/existingEntry instanceof DefaultViewConfigEntry
                    && ((DefaultViewConfigEntry)existingEntry).isSimpleEntryMode())
            {
                //in this case the alternative view-controller approach which just adds page-beans was invoked before
                //-> we just have to use the page bean of the existing entry

                //here we have a simple-entry!   (which just contains page-bean definitions)
                for(PageBeanConfigEntry pageBeanConfigEntry : existingEntry.getPageBeanDefinitions())
                {
                    //add page-beans to the real entry
                    newEntry.addPageBean(pageBeanConfigEntry.getBeanClass());
                }
                ViewConfigCache.replaceViewDefinition(newEntry.getViewId(), newEntry);
                return;
            }

            //add created entry
            //if there is already an normal (not simple!) entry force an exception
            ViewConfigCache.addViewDefinition(newEntry.getViewId(), newEntry);
        }
    }

    /**
     * important: {@link org.apache.myfaces.extensions.cdi.core.api.config.view.View#inline()} isn't supported!
     *
     * @param annotatedType current annotated type
     */
    private void addPageBean(AnnotatedType annotatedType)
    {
        View view = annotatedType.getAnnotation(View.class);

        if(!"".equals(view.inline()[0]))
        {
            //TODO move exceptions to util class
            throw new IllegalStateException("Definition error at: " + annotatedType.getJavaClass().getName() +
                    " it isn't allowed to define a class level @" + View.class.getName() +
                    " without a typesafe view config. Please don't use @View(inline=\"...\") for this use-case!");
        }

        String viewId;
        for(Class<? extends ViewConfig> viewConfigClass : view.value())
        {
            ViewConfigEntry viewConfigEntry = ViewConfigCache.getViewDefinition(viewConfigClass);

            if(viewConfigEntry == null)
            {
                ViewConfigEntry entry = createViewConfigEntry(viewConfigClass);

                if(entry != null)
                {
                    entry.addPageBean(annotatedType.getJavaClass());

                    //TODO introduce an SPI with a better name
                    if(entry instanceof DefaultViewConfigEntry)
                    {
                        ((DefaultViewConfigEntry)entry).activateSimpleEntryMode();
                    }
                    ViewConfigCache.addViewDefinition(entry.getViewId(), entry);
                }
            }
            else
            {
                viewConfigEntry.addPageBean(annotatedType.getJavaClass());
            }
        }
    }

    protected ViewConfigEntry createViewConfigEntry(Class pageDefinitionClass)
    {
        if(!ViewConfig.class.isAssignableFrom(pageDefinitionClass))
        {
            throw new IllegalArgumentException(
                    "the page definition " + pageDefinitionClass.getName() + " has to implement "
                            + ViewConfig.class.getName());
        }

        @SuppressWarnings({"unchecked"})
        Class<? extends ViewConfig> viewDefinitionClass = (Class<? extends ViewConfig>)pageDefinitionClass;

        //we use abstract classes for nesting definitions
        //TODO log a warning in case of project-stage dev
        if(Modifier.isAbstract(viewDefinitionClass.getModifiers()))
        {
            return null;
        }

        ViewConfigExtractor viewConfigExtractor = CodiUtils.lookupFromEnvironment(VIEW_CONFIG_EXTRACTOR_PROPERTY_NAME,
                                                                                  VIEW_CONFIG_EXTRACTOR_JNDI_NAME,
                                                                                  ViewConfigExtractor.class);
       
        if(viewConfigExtractor == null)
        {
            viewConfigExtractor = new DefaultViewConfigExtractor();
        }

        ViewConfigEntry result = viewConfigExtractor.extractViewConfig(viewDefinitionClass);
        return result;
    }

    public boolean isActivated()
    {
        return ClassDeactivation.isClassActivated(getClass());
    }
}
TOP

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

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.