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
015package org.apache.tapestry5.internal.transform;
016
017import org.apache.tapestry5.EventConstants;
018import org.apache.tapestry5.annotations.PageActivationContext;
019import org.apache.tapestry5.model.MutableComponentModel;
020import org.apache.tapestry5.plastic.FieldHandle;
021import org.apache.tapestry5.plastic.PlasticClass;
022import org.apache.tapestry5.plastic.PlasticField;
023import org.apache.tapestry5.runtime.Component;
024import org.apache.tapestry5.runtime.ComponentEvent;
025import org.apache.tapestry5.services.ComponentEventHandler;
026import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
027import org.apache.tapestry5.services.transform.TransformationSupport;
028
029import java.util.List;
030
031/**
032 * Provides the page activation context handlers.
033 *
034 * @see org.apache.tapestry5.annotations.PageActivationContext
035 */
036public 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}