Package com.adaptivui.tapestry5.genetify.internal

Source Code of com.adaptivui.tapestry5.genetify.internal.GenetifyWorker

//
// Copyright 2012 Nourredine Khadri
//
// 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.
//

package com.adaptivui.tapestry5.genetify.internal;

import org.apache.tapestry5.annotations.CleanupRender;
import org.apache.tapestry5.func.F;
import org.apache.tapestry5.func.Worker;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.plastic.ComputedValue;
import org.apache.tapestry5.plastic.FieldHandle;
import org.apache.tapestry5.plastic.InstanceContext;
import org.apache.tapestry5.plastic.MethodAdvice;
import org.apache.tapestry5.plastic.MethodInvocation;
import org.apache.tapestry5.plastic.PlasticClass;
import org.apache.tapestry5.plastic.PlasticField;
import org.apache.tapestry5.plastic.PlasticMethod;
import org.apache.tapestry5.services.TransformConstants;
import org.apache.tapestry5.services.javascript.InitializationPriority;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
import org.apache.tapestry5.services.transform.TransformationSupport;

import com.adaptivui.tapestry5.genetify.annotations.Genetify;
import com.adaptivui.tapestry5.genetify.config.GenetifyConstants;
import com.adaptivui.tapestry5.genetify.data.GeneType;

/**
* This worker adds the logic to add the genetify client stack for a page or during a render phase.
*
*/
public class GenetifyWorker implements ComponentClassTransformWorker2
{
  private final JavaScriptSupport javascriptSupport;

  private final Worker<GeneType> addVaryScript = new Worker<GeneType>()
  {
    public void work(GeneType geneType)
    {
      if(geneType != GeneType.NONE){
        /**
         * Call the Genetify's "vary()" function very early
         * Not very elegant but fulfills Genetify's requirements and does the job
         **/
        javascriptSupport.addScript(
            InitializationPriority.IMMEDIATE,
            String.format("genetify.vary('%s');",
            geneType.getLabel()));
      }
    }
  };

  public GenetifyWorker(JavaScriptSupport javascriptSupport)
  {
    this.javascriptSupport = javascriptSupport;
  }

  public void transform(PlasticClass componentClass, TransformationSupport support, MutableComponentModel model)
  {
    processClassAnnotationAtCleanupRenderPhase(componentClass, model);
   
    for (PlasticMethod m : componentClass.getMethodsWithAnnotation(Genetify.class))
        {
      decorateMethod(componentClass, model, m);
        }
  }

  private void decorateMethod(PlasticClass componentClass, MutableComponentModel model, PlasticMethod method)
    {
        Genetify annotation = method.getAnnotation(Genetify.class);
       
        decorateMethodForAddingScript(componentClass, model, method, annotation);
    }

  private void processClassAnnotationAtCleanupRenderPhase(PlasticClass componentClass, MutableComponentModel model)
  {
    Genetify annotation = componentClass.getAnnotation(Genetify.class);

    if (annotation != null)
    {
      /**
       * It seems that Tapestry ignores the method annotation when you override the method
       * So we choose to override the cleanupRender phase as it has less chance to be annotated with @Genetify 
       * */
      PlasticMethod cleanupRender = componentClass.introduceMethod(TransformConstants.CLEANUP_RENDER_DESCRIPTION);

      decorateMethodForAddingScript(componentClass, model, cleanupRender, annotation);

      model.addRenderPhase(CleanupRender.class);
    }
  }

  private void decorateMethodForAddingScript(PlasticClass componentClass, MutableComponentModel model, PlasticMethod method,
      Genetify annotation)
  {
    addVaryScript(componentClass, model, method, annotation.vary());

  }

  private void addVaryScript(PlasticClass plasticClass, MutableComponentModel model, PlasticMethod method,
      GeneType[] geneTypes)
  {
    decorateMethodWithOperation(plasticClass, model, method, geneTypes, addVaryScript);
  }

  private void decorateMethodWithOperation(PlasticClass componentClass, MutableComponentModel model,
      PlasticMethod method, GeneType[] geneTypes, Worker<GeneType> operation)
  {
    if (geneTypes == null || geneTypes.length == 0)
      return;

    PlasticField geneTypesField = componentClass.introduceField(GeneType[].class,
        "varyTypes_" + method.getDescription().methodName);

    initializeGeneTypes(model.getBaseResource(), geneTypes, geneTypesField);

    addMethodGeneTypesOperationAdvice(method, geneTypesField.getHandle(), operation);
  }

  private void initializeGeneTypes(final Resource baseResource,
      final GeneType[] geneTypes, final PlasticField geneTypesField)
  {
    geneTypesField.injectComputed(new ComputedValue<GeneType[]>()
      {
        public GeneType[] get(InstanceContext context)
        {
          return geneTypes;
        }
      });
  }

  private void addMethodGeneTypesOperationAdvice(PlasticMethod method, final FieldHandle access,
      final Worker<GeneType> operation)
  {
    method.addAdvice(new MethodAdvice()
    {
      public void advise(MethodInvocation invocation)
      {
        javascriptSupport.importStack(GenetifyConstants.GENETIFY_STACK);
       
        GeneType[] geneTypes = (GeneType[]) access.get(invocation.getInstance());

        F.flow(geneTypes).each(operation);

        invocation.proceed();
      }
    });
  }
}

TOP

Related Classes of com.adaptivui.tapestry5.genetify.internal.GenetifyWorker

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.