    001    // Copyright 2008, 2009, 2010, 2011 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    // http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.transform;
    016
    017    import org.apache.tapestry5.EventConstants;
    018    import org.apache.tapestry5.annotations.PageActivationContext;
    019    import org.apache.tapestry5.model.MutableComponentModel;
    020    import org.apache.tapestry5.plastic.FieldHandle;
    021    import org.apache.tapestry5.plastic.PlasticClass;
    022    import org.apache.tapestry5.plastic.PlasticField;
    023    import org.apache.tapestry5.runtime.Component;
    024    import org.apache.tapestry5.runtime.ComponentEvent;
    025    import org.apache.tapestry5.services.ComponentEventHandler;
    026    import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
    027    import org.apache.tapestry5.services.transform.TransformationSupport;
    028
    029    import java.util.List;
    030
    031    /**
    032     * Provides the page activation context handlers.
    033     *
    034     * @see org.apache.tapestry5.annotations.PageActivationContext
    035     */
    036    public class PageActivationContextWorker implements ComponentClassTransformWorker2
    037    {
    038        public void transform(PlasticClass plasticClass, TransformationSupport support, MutableComponentModel model)
    039        {
    040            List<PlasticField> fields = plasticClass.getFieldsWithAnnotation(PageActivationContext.class);
    041
    042            switch (fields.size())
    043            {
    044                case 0:
    045                    break;
    046
    047                case 1:
    048
    049                    transformField(support, fields.get(0));
    050
    051                    break;
    052
    053                default:
    054
    055                    throw new RuntimeException(TransformMessages.illegalNumberOfPageActivationContextHandlers2(fields));
    056            }
    057        }
    058
    059        private void transformField(TransformationSupport support, PlasticField field)
    060        {
    061            PageActivationContext annotation = field.getAnnotation(PageActivationContext.class);
    062
    063            FieldHandle handle = field.getHandle();
    064
    065            if (annotation.activate())
    066            {
    067                support.addEventHandler(EventConstants.ACTIVATE, 1,
    068                        "PageActivationContextWorker activate event handler",
    069                        createActivationHandler(field.getTypeName(), handle));
    070            }
    071
    072            if (annotation.passivate())
    073            {
    074                support.addEventHandler(EventConstants.PASSIVATE, 0,
    075                        "PageActivationContextWorker passivate event handler", createPassivateHandler(handle));
    076            }
    077
    078            // We don't claim the field, and other workers may even replace it with a FieldConduit.
    079
    080        }
    081
    082        private static ComponentEventHandler createActivationHandler(final String fieldType, final FieldHandle handle)
    083        {
    084            return new ComponentEventHandler()
    085            {
    086                public void handleEvent(Component instance, ComponentEvent event)
    087                {
    088                    Object value = event.coerceContext(0, fieldType);
    089
    090                    handle.set(instance, value);
    091                }
    092            };
    093        }
    094
    095        private static ComponentEventHandler createPassivateHandler(final FieldHandle handle)
    096        {
    097            return new ComponentEventHandler()
    098            {
    099                public void handleEvent(Component instance, ComponentEvent event)
    100                {
    101                    Object value = handle.get(instance);
    102
    103                    event.storeResult(value);
    104                }
    105            };
    106        }
    107    }