Package com.adaptivui.tapestry5.genetify.internal

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

//
// 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.json.JSONObject;
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.JavaScriptSupport;
import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
import org.apache.tapestry5.services.transform.TransformationSupport;

import com.adaptivui.tapestry5.genetify.annotations.Goal;
import com.adaptivui.tapestry5.genetify.config.GenetifyConstants;

/**
* This worker adds the logic to add the genetify client stack for the page if not already done.
* It also calls the genetify's record goal function on page's onload event
*
*/
public class GoalWorker implements ComponentClassTransformWorker2
{
  private final JavaScriptSupport javascriptSupport;

  private final Worker<com.adaptivui.tapestry5.genetify.data.Goal> addGoalScript = new Worker<com.adaptivui.tapestry5.genetify.data.Goal>()
  {
    public void work(com.adaptivui.tapestry5.genetify.data.Goal goal)
    {
      /**
       * Call the Genetify's "record.goal()" function
       **/
      if(goal.getScore() != 0){
        JSONObject spec = new JSONObject();
        spec.put("label", goal.getLabel());
        spec.put("score", goal.getScore());
        javascriptSupport.addInitializerCall("recordGoal", spec);
      }
    }
  };

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

  public void transform(PlasticClass componentClass, TransformationSupport support, MutableComponentModel model)
  {
    processClassAnnotationAtCleanupRenderPhase(componentClass, model);
  }

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

    if (annotation != null)
    {
      /**
       * It seems that Tapestry ignores the annotation method when it is overridden
       * So we choose the cleanupRender phase as it is the method that has less chance to be annotated with @Goal 
       * */
      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,
      Goal annotation)
  {
    addGoalScript(componentClass,
            model,
            method,
            new com.adaptivui.tapestry5.genetify.data.Goal(annotation.label(), annotation.score()));
  }

  private void addGoalScript(PlasticClass plasticClass, MutableComponentModel model, PlasticMethod method,
      com.adaptivui.tapestry5.genetify.data.Goal goal)
  {
    decorateMethodWithOperation(plasticClass, model, method, goal, addGoalScript);
  }

  private void decorateMethodWithOperation(PlasticClass componentClass, MutableComponentModel model,
      PlasticMethod method, com.adaptivui.tapestry5.genetify.data.Goal goal, Worker<com.adaptivui.tapestry5.genetify.data.Goal> operation)
  {
    if (goal == null)
      return;

    PlasticField goalField = componentClass.introduceField(com.adaptivui.tapestry5.genetify.data.Goal.class,
        "goal_" + method.getDescription().methodName);

    initializeGoal(method, goal, goalField);

    addMethodGoalOperationAdvice(method, goalField.getHandle(), operation);
  }

  private void initializeGoal(final PlasticMethod method,
      final com.adaptivui.tapestry5.genetify.data.Goal goal, final PlasticField goalField)
  {
    goalField.injectComputed(new ComputedValue<com.adaptivui.tapestry5.genetify.data.Goal>()
    {
      public com.adaptivui.tapestry5.genetify.data.Goal get(InstanceContext context)
      {
        if (goal.getLabel() == null || goal.getLabel().length() == 0){
          goal.setLabel(method.getDescription().methodName);
        }
        return goal;
      }
    });
  }

  private void addMethodGoalOperationAdvice(PlasticMethod method, final FieldHandle access,
      final Worker<com.adaptivui.tapestry5.genetify.data.Goal> operation)
  {
    method.addAdvice(new MethodAdvice()
    {
      public void advise(MethodInvocation invocation)
      {
        javascriptSupport.importStack(GenetifyConstants.GENETIFY_STACK);
       
        com.adaptivui.tapestry5.genetify.data.Goal goal = (com.adaptivui.tapestry5.genetify.data.Goal) access.get(invocation.getInstance());

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

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

TOP

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

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.