Package org.apache.beehive.netui.pageflow.internal

Source Code of org.apache.beehive.netui.pageflow.internal.JavaControlUtils

/*
* Copyright 2004 The Apache Software Foundation.
*
* 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.
*
* $Header:$
*/
package org.apache.beehive.netui.pageflow.internal;

import java.beans.beancontext.BeanContext;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.HashSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;

import org.apache.beehive.controls.api.bean.Controls;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.bean.Control;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
import org.apache.beehive.netui.pageflow.ControlFieldInitializationException;
import org.apache.beehive.netui.pageflow.PageFlowManagedObject;
import org.apache.beehive.netui.pageflow.PageFlowUtils;
import org.apache.beehive.netui.pageflow.PageFlowControlContainerFactory;
import org.apache.beehive.netui.pageflow.PageFlowControlContainer;
import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
import org.apache.beehive.netui.util.logging.Logger;

/**
* @exclude
*/
public class JavaControlUtils
{
    private static final Logger LOG = Logger.getInstance( JavaControlUtils.class );
    private static final String CONTROL_ANNOTATION_CLASSNAME = Control.class.getName();

    /** Map of control-container-class (e.g., PageFlowController) to Map of fields/control-properties. */
    private static InternalConcurrentHashMap/*< String, Map< Field, PropertyMap > >*/ _controlFieldCache =
            new InternalConcurrentHashMap/*< String, Map< Field, PropertyMap > >*/();

    public static void destroyControl( Object controlInstance )
    {
        assert controlInstance instanceof ControlBean : controlInstance.getClass().getName();
        BeanContext beanContext = ( ( ControlBean ) controlInstance ).getBeanContext();
        if ( beanContext != null ) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Removing control " + controlInstance + " from ControlBeanContext " + beanContext);
            }
            beanContext.remove( controlInstance );
        }
    }

    /**
     * @return a map of Field (accessible) -> AnnotationMap
     */
    private static Map getAccessibleControlFieldAnnotations( Class controlClientClass, ServletContext servletContext )
    {
        String className = controlClientClass.getName();

        //
        // Reading the annotations is expensive.  See if there's a cached copy of the map.
        //
        Map/*< Field, PropertyMap >*/ cached = ( Map ) _controlFieldCache.get( className );

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


        HashMap/*< Field, PropertyMap >*/ ret = new HashMap/*< Field, PropertyMap >*/();
        boolean accessPrivateFields = true;

        // Note that the annnotation reader doesn't change per-class.  Inherited annotated elements are all read.
        AnnotationReader annReader = AnnotationReader.getAnnotationReader( controlClientClass, servletContext );

        //
        // Go through this class and all superclasses, looking for control fields.  Make sure that a superclass control
        // field never replaces a subclass control field (this is what the 'fieldNames' HashSet is for).
        //
        HashSet fieldNames = new HashSet();
        do {
            Field[] fields = controlClientClass.getDeclaredFields();

            for ( int i = 0; i < fields.length; i++ )
            {
                Field field = fields[i];
                String fieldName = field.getName();
                int modifiers = field.getModifiers();

                if ( ! fieldNames.contains( fieldName ) && ! Modifier.isStatic( modifiers )
                     && annReader.getAnnotation( field.getName(), CONTROL_ANNOTATION_CLASSNAME ) != null )
                {
                    if ( accessPrivateFields || ! Modifier.isPrivate( modifiers ) )
                    {
                        if ( ! Modifier.isPublic( field.getModifiers() ) ) field.setAccessible( true );
                        ret.put( field, new AnnotatedElementMap( field ) );
                        fieldNames.add( fieldName );
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("Found control field " + fieldName + " in control client class "
                                       + controlClientClass.getName());
                        }
                    }
                }
            }

            accessPrivateFields = false;
            controlClientClass = controlClientClass.getSuperclass();
        } while ( controlClientClass != null );

        _controlFieldCache.put( className, ret );
        return ret;
    }

    /**
     * Initialize all null member variables that are Java Controls.
     *
     * @param request the current HttpServletRequest
     * @param response the current HttpServletRequest
     * @param servletContext the ServletContext
     * @param controlClient the class with possible annotated Control fields
     * @throws org.apache.beehive.netui.pageflow.ControlFieldInitializationException
     */
    public static void initJavaControls( HttpServletRequest request, HttpServletResponse response,
                                         ServletContext servletContext, PageFlowManagedObject controlClient )
        throws ControlFieldInitializationException
    {
        Class controlClientClass = controlClient.getClass();

        //
        // First, just return if there are no annotated Control fields.  This saves us from having to catch a
        // (wrapped) ClassNotFoundException for the control client initializer if we were to simply call
        // Controls.initializeClient().
        //
        Map controlFields = getAccessibleControlFieldAnnotations( controlClientClass, servletContext );
        if ( controlFields.isEmpty() ) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("No control field annotations were found for " + controlClient);
            }
            PageFlowControlContainer pfcc = PageFlowControlContainerFactory.getControlContainer(request,servletContext);
            pfcc.beginContextOnPageFlow(controlClient,request,response,servletContext);
            return;
        }

        request = PageFlowUtils.unwrapMultipart( request );

        PageFlowControlContainer pfcc = PageFlowControlContainerFactory.getControlContainer(request,servletContext);
        pfcc.createAndBeginControlBeanContext(controlClient,request,response,servletContext);
        ControlBeanContext beanContext = pfcc.getControlContainerContext(controlClient);
        assert beanContext != null : "ControlBeanContext was not initialized by PageFlowRequestProcessor";

        try
        {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Initializing control client " + controlClient);
            }
            Controls.initializeClient(null, controlClient, beanContext);
        }
        catch ( Exception e )
        {
            LOG.error( "Exception occurred while initializing controls", e);
            throw new ControlFieldInitializationException( controlClientClass.getName(), controlClient, e );
        }
    }

    /**
     * Clean up all member variables that are Java Controls.
     */
    public static void uninitJavaControls( ServletContext servletContext, PageFlowManagedObject controlClient )
    {
        Map controlFields = getAccessibleControlFieldAnnotations( controlClient.getClass(), servletContext );

        for ( Iterator i = controlFields.keySet().iterator(); i.hasNext(); )
        {
            Field controlField = ( Field ) i.next();

            try
            {
                Object fieldValue = controlField.get( controlClient );

                if ( fieldValue != null )
                {
                    controlField.set( controlClient, null );
                    destroyControl( fieldValue );
                }
            }
            catch ( IllegalAccessException e )
            {
                LOG.error( "Exception while uninitializing Java Control " + controlField.getName(), e );
            }
        }
    }
}
TOP

Related Classes of org.apache.beehive.netui.pageflow.internal.JavaControlUtils

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.