Package er.wojrebel

Source Code of er.wojrebel.WOJRebelClassReloadHandler$WOEventClassListener

package er.wojrebel;

import java.util.Enumeration;

import org.zeroturnaround.javarebel.ClassEventListener;
import org.zeroturnaround.javarebel.Logger;
import org.zeroturnaround.javarebel.LoggerFactory;
import org.zeroturnaround.javarebel.Reloader;
import org.zeroturnaround.javarebel.ReloaderFactory;

import com.webobjects.appserver.WOAction;
import com.webobjects.appserver.WOApplication;
import com.webobjects.appserver.WOComponent;
import com.webobjects.appserver.WORequest;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSNotification;
import com.webobjects.foundation.NSValidation;

/**
* WOJRebelClassReloadHandler manages the clearing of KVC, component definition and class caches
* when a class is reloaded by JRebel. Any cached ClassNotFound entries are also removed.
*
* @author qdolan
*
*/
public class WOJRebelClassReloadHandler {

  private static boolean initialized = false;
   
  private boolean resetKVCCaches = false;
  private boolean resetComponentCache = false;
  private boolean resetActionClassCache = false;
  private boolean resetValidationCache = false;

  private static final WOJRebelClassReloadHandler instance = new WOJRebelClassReloadHandler();
  private static final Logger log = LoggerFactory.getInstance();

  private WOJRebelClassReloadHandler() { /* Private */ }
 
  public static WOJRebelClassReloadHandler getInstance() {
    return instance;
  }

  private void doReset() {
    if (resetKVCCaches) {
      resetKVCCaches = false;
      log.echo("JRebel: Resetting KeyValueCoding caches");
      NSKeyValueCoding.DefaultImplementation._flushCaches();
      NSKeyValueCoding._ReflectionKeyBindingCreation._flushCaches();
      NSKeyValueCoding.ValueAccessor._flushCaches();
    }
    if (resetComponentCache) {
      resetComponentCache = false;
      log.echo("JRebel: Resetting Component Definition cache");
      WOApplication.application()._removeComponentDefinitionCacheContents();
    }
    if (resetActionClassCache) {
      resetActionClassCache = false;
      log.echo("JRebel: Resetting Action class cache");
      WOClassCacheAccessor.clearActionClassCache();
    }
    if (resetValidationCache) {
      resetValidationCache = false;
      log.echo("JRebel: Resetting NSValidation cache");
      NSValidation.DefaultImplementation._flushCaches();
    }
  }

  public void initialize() {
    if (initialized) {
      return;
    }

    initialized = true;

    if (WOApplication.application() != null && WOApplication.application().isCachingEnabled()) {
      System.out.println("Running in deployment mode. Rapid turnaround is disabled");
      return;
    }

    if (!isReloadEnabled()) {
      System.out.println("JRebel rapid turnaround mode is disabled because JRebel is not running "
          + "\n    To use JRebel rapid turnaround you must add the following to your "
          + "Java VM arguments:\n        -noverify -javaagent:<pathtojar>/jrebel.jar");
      System.out.println("    JRebel can be obtained from www.zeroturnaround.com");
      return;
    }

    log.echo("JRebel: WebObjects support enabled");
    WOEventClassListener listener = new WOEventClassListener();
    Reloader reloader = ReloaderFactory.getInstance();
    reloader.addClassReloadListener(listener);
  }

  @SuppressWarnings("all")
  public void reloaded(Class clazz) {
    resetKVCCaches = true;
    if (WOComponent.class.isAssignableFrom(clazz)) {
      resetComponentCache = true;
    }
    if (WOAction.class.isAssignableFrom(clazz)) {
      resetActionClassCache = true;
    }
    if (NSValidation.class.isAssignableFrom(clazz)) {
      resetValidationCache = true;
    }
    doReset();
  }
 
  @SuppressWarnings("unchecked")
  public synchronized void updateLoadedClasses(NSNotification notification) {
    Reloader reloader = ReloaderFactory.getInstance();
    if (notification != null) {
      WORequest request = (WORequest) notification.object();
      String key = "/" + WOApplication.application().resourceRequestHandlerKey();
      if (request.uri().indexOf(request.adaptorPrefix()) != 0 || request.uri().indexOf(key) >= 0) {
        return;
      }
    }
    NSDictionary classList = WOClassCacheAccessor.getClassCache();
    String unknownClassName = "com.webobjects.foundation._NSUtilities$_NoClassUnderTheSun";
    Class<?> unknownClass = WOClassCacheAccessor.classForName(unknownClassName);
    Enumeration<String> en = classList.keyEnumerator();
    while(en.hasMoreElements()) {
      String className = en.nextElement();
      if (className.equals(unknownClassName)) {
        continue;
      }
      Class<?> clazz = WOClassCacheAccessor.classForName(className);

      if (clazz != null && clazz.isPrimitive()) {
        continue;
      }

      if (clazz == null || clazz.equals(unknownClass)) {
        WOClassCacheAccessor.removeClassForName(className);
        continue;
      }
      reloader.checkAndReload(clazz);
    }
    doReset();
  }

  public boolean isReloadEnabled() {
    return ReloaderFactory.getInstance().isReloadEnabled();
  }

  private class WOEventClassListener implements ClassEventListener {
    public void onClassEvent(int eventType, Class clazz) {
      if (eventType == ClassEventListener.EVENT_RELOADED) {
        reloaded(clazz);
      }
    }

    public int priority() {
      return 0;
    }
  }
}
TOP

Related Classes of er.wojrebel.WOJRebelClassReloadHandler$WOEventClassListener

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.