001    // Copyright 2007, 2008, 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.MarkupWriter;
018    import org.apache.tapestry5.internal.InternalComponentResources;
019    import org.apache.tapestry5.model.MutableComponentModel;
020    import org.apache.tapestry5.plastic.MethodDescription;
021    import org.apache.tapestry5.plastic.PlasticClass;
022    import org.apache.tapestry5.plastic.PlasticField;
023    import org.apache.tapestry5.plastic.PlasticUtils;
024    import org.apache.tapestry5.runtime.RenderCommand;
025    import org.apache.tapestry5.runtime.RenderQueue;
026    import org.apache.tapestry5.services.TransformConstants;
027    import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
028    import org.apache.tapestry5.services.transform.TransformationSupport;
029    
030    /**
031     * Ensures that all components implement {@link RenderCommand} by delegating to
032     * {@link InternalComponentResources#render(org.apache.tapestry5.MarkupWriter, org.apache.tapestry5.runtime.RenderQueue)}.
033     * This is also responsible for invoking {@link org.apache.tapestry5.internal.InternalComponentResources#postRenderCleanup()}
034     */
035    public class RenderCommandWorker implements ComponentClassTransformWorker2
036    {
037    
038        private final MethodDescription RENDER_DESCRIPTION = PlasticUtils.getMethodDescription(RenderCommand.class, "render", MarkupWriter.class, RenderQueue.class);
039    
040        public void transform(PlasticClass plasticClass, TransformationSupport support, MutableComponentModel model)
041        {
042            // Subclasses don't need to bother, they'll inherit from super-classes.
043    
044            if (!support.isRootTransformation())
045            {
046                return;
047            }
048    
049            plasticClass.introduceInterface(RenderCommand.class);
050    
051            PlasticField resourcesField = plasticClass.introduceField(InternalComponentResources.class, "resources").injectFromInstanceContext();
052    
053            plasticClass.introduceMethod(RENDER_DESCRIPTION).delegateTo(resourcesField);
054    
055            plasticClass.introduceMethod(TransformConstants.POST_RENDER_CLEANUP_DESCRIPTION).delegateTo(resourcesField);
056        }
057    }