/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.pojo.interceptors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.joinpoint.Invocation;
import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.pojo.impl.InternalConstant;
import org.jboss.cache.pojo.impl.PojoCacheImpl;

import java.lang.reflect.Field;

/**
 * interceptor to intercept for static field replication.
 *
 * @author Ben Wang
 */

public class StaticFieldInterceptor implements Interceptor
{
   private final Log log_ = LogFactory.getLog(StaticFieldInterceptor.class);
   private PojoCacheImpl pCache_;
   private Fqn fqn_;
   private String name_;
   private String key_;

   public StaticFieldInterceptor()
   {
   }

   public String getName()
   {
      if (name_ == null)
      {
         this.name_ = "StaticFieldInterceptor on [" + fqn_ + "]";
      }
      return name_;
   }

   public Object invoke(Invocation invocation) throws Throwable
   {
      /*
      // Kind of ad hoc now. MethodInvocation should not invoke this.
      if(invocation instanceof MethodInvocation)
         return invocation.invokeNext();

      needInit(((FieldInvocation)invocation).getField());
      if (invocation instanceof FieldWriteInvocation)
      {
         FieldInvocation fieldInvocation =
                 (FieldInvocation) invocation;

         Advisor advisor = fieldInvocation.getAdvisor();
         Field field = fieldInvocation.getField();
         if(log_.isTraceEnabled())
         {
            log_.trace("invoke(): field write interception for fqn: " +fqn_ + " and field: " +field);
         }

         // Only if this field is replicatable. static, transient and final are not.
         Object value = ((FieldWriteInvocation) fieldInvocation).getValue();

         cache_.put(fqn_, key_, value);
         Object obj = fieldInvocation.getTargetObject();
      } else if (invocation instanceof FieldReadInvocation)
      {
         FieldInvocation fieldInvocation =
                 (FieldInvocation) invocation;
         Field field = fieldInvocation.getField();
         Advisor advisor = fieldInvocation.getAdvisor();
         return cache_.get(fqn_, key_);
      }
      */
      return invocation.invokeNext();

   }

   private void needInit(Field field)
   {
      if (pCache_ == null)
      {
         String cn = field.getDeclaringClass().getName();
         fqn_ = Fqn.fromString(InternalConstant.JBOSS_INTERNAL_STATIC + "/" + cn);
         key_ = field.getName();
      }
   }

   boolean isChildOf(Fqn parentFqn)
   {
      return fqn_.isChildOf(parentFqn);
   }

   public Fqn getFqn()
   {
      return fqn_;
   }

   public void setFqn(Fqn fqn)
   {
      this.fqn_ = fqn;
   }

}
