htmlunit-2.7

;
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManager
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

public abstract class JavaScriptJob
  implements Runnable
{
  private Integer id_;
  private final int initialDelay_;
  private final Integer period_;
  
  public JavaScriptJob()
  {
    this(0, null);
  }
  
  public JavaScriptJob(int initialDelay, Integer period)
  {
    initialDelay_ = initialDelay;
    period_ = period;
  }
  
  public void setId(Integer id)
  {
    id_ = id;
  }
  
  public Integer getId()
  {
    return id_;
  }
  
  public int getInitialDelay()
  {
    return initialDelay_;
  }
  
  public Integer getPeriod()
  {
    return period_;
  }
  
  public boolean isPeriodic()
  {
    return period_ != null;
  }
  
  public String toString()
  {
    return "JavaScript Job " + id_;
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJob
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.lang.ref.WeakReference;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class JavaScriptExecutionJob
  extends JavaScriptJob
{
  private static final Log LOG = LogFactory.getLog(JavaScriptExecutionJob.class);
  private final String label_;
  private final WeakReference<WebWindow> window_;
  
  public JavaScriptExecutionJob(int initialDelay, Integer period, String label, WebWindow window)
  {
    super(initialDelay, period);
    label_ = label;
    window_ = new WeakReference(window);
  }
  
  public void run()
  {
    WebWindow w = (WebWindow)window_.get();
    if (w == null) {
      return;
    }
    if (LOG.isDebugEnabled()) {
      LOG.debug("Executing " + this + ".");
    }
    try
    {
      HtmlPage page = (HtmlPage)w.getEnclosedPage();
      if ((w.getEnclosedPage() != page) || (!w.getWebClient().getWebWindows().contains(w))) {
        LOG.debug("The page that originated this job doesn't exist anymore. Execution cancelled.");
      } else {
        runJavaScript(page);
      }
    }
    finally
    {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Finished executing " + this + ".");
      }
    }
  }
  
  public String toString()
  {
    return "JavaScript Execution Job " + getId() + ": " + label_;
  }
  
  protected abstract void runJavaScript(HtmlPage paramHtmlPage);
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutionJob
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;

public class JavaScriptFunctionJob
  extends JavaScriptExecutionJob
{
  private final Function function_;
  
  public JavaScriptFunctionJob(int initialDelay, Integer period, String label, WebWindow window, Function function)
  {
    super(initialDelay, period, label, window);
    function_ = function;
  }
  
  protected void runJavaScript(HtmlPage page)
  {
    HtmlElement doc = page.getDocumentElement();
    Scriptable scriptable = (Scriptable)page.getEnclosingWindow().getScriptObject();
    page.executeJavaScriptFunctionIfPossible(function_, scriptable, new Object[0], doc);
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptFunctionJob
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

import java.util.List;
import org.apache.commons.logging.Log;

class JavaScriptJobManagerImpl$ExecutingJobTracker
  implements Runnable
{
  private final JavaScriptJob job_;
  
  JavaScriptJobManagerImpl$ExecutingJobTracker(JavaScriptJobManagerImpl paramJavaScriptJobManagerImpl, JavaScriptJob job)
  {
    job_ = job;
  }
  
  public void run()
  {
    JavaScriptJobManagerImpl.access$000().debug("Running job " + job_);
    synchronized (JavaScriptJobManagerImpl.access$100(this$0))
    {
      JavaScriptJobManagerImpl.access$100(this$0).add(job_);
      JavaScriptJobManagerImpl.access$100(this$0).notifyAll();
    }
    try
    {
      job_.run();
    }
    catch (RuntimeException e)
    {
      JavaScriptJobManagerImpl.access$000().error("Job run failed with unexpected RuntimeException: " + e.getMessage(), e);
      throw e;
    }
    finally
    {
      synchronized (JavaScriptJobManagerImpl.access$100(this$0))
      {
        JavaScriptJobManagerImpl.access$100(this$0).remove(job_);
        JavaScriptJobManagerImpl.access$100(this$0).notifyAll();
      }
    }
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl.ExecutingJobTracker
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

class JavaScriptJobManagerImpl$1
  implements ThreadFactory
{
  JavaScriptJobManagerImpl$1(JavaScriptJobManagerImpl paramJavaScriptJobManagerImpl) {}
  
  public Thread newThread(Runnable r)
  {
    String name = "JavaScript Job Thread " + JavaScriptJobManagerImpl.access$200().getAndIncrement();
    JavaScriptJobManagerImpl.access$302(this$0, new Thread(r, name));
    JavaScriptJobManagerImpl.access$300(this$0).setDaemon(true);
    JavaScriptJobManagerImpl.access$300(this$0).setPriority(JavaScriptJobManagerImpl.access$400());
    return JavaScriptJobManagerImpl.access$300(this$0);
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl.1
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebWindow;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JavaScriptJobManagerImpl
  implements JavaScriptJobManager
{
  private static final long serialVersionUID = 9212855747249248967L;
  private transient WeakReference<WebWindow> window_;
  private transient ScheduledThreadPoolExecutor executor_;
  private transient Map<Integer, ScheduledFuture<?>> futures_;
  private transient List<JavaScriptJob> currentlyRunningJobs_;
  private static final AtomicInteger NEXT_JOB_ID = new AtomicInteger(1);
  private static final AtomicInteger NEXT_THREAD_ID = new AtomicInteger(1);
  private static final int PRIORITY = Math.min(10, Thread.currentThread().getPriority() + 1);
  private static final Log LOG = LogFactory.getLog(JavaScriptJobManagerImpl.class);
  private Thread executorThread_;
  
  class ExecutingJobTracker
    implements Runnable
  {
    private final JavaScriptJob job_;
    
    ExecutingJobTracker(JavaScriptJob job)
    {
      job_ = job;
    }
    
    public void run()
    {
      JavaScriptJobManagerImpl.LOG.debug("Running job " + job_);
      synchronized (currentlyRunningJobs_)
      {
        currentlyRunningJobs_.add(job_);
        currentlyRunningJobs_.notifyAll();
      }
      try
      {
        job_.run();
      }
      catch (RuntimeException e)
      {
        JavaScriptJobManagerImpl.LOG.error("Job run failed with unexpected RuntimeException: " + e.getMessage(), e);
        throw e;
      }
      finally
      {
        synchronized (currentlyRunningJobs_)
        {
          currentlyRunningJobs_.remove(job_);
          currentlyRunningJobs_.notifyAll();
        }
      }
    }
  }
  
  public JavaScriptJobManagerImpl(WebWindow window)
  {
    init(window);
  }
  
  private void init(WebWindow window)
  {
    window_ = new WeakReference(window);
    executor_ = new ScheduledThreadPoolExecutor(1);
    futures_ = new TreeMap();
    currentlyRunningJobs_ = new ArrayList();
    executor_.setThreadFactory(new ThreadFactory()
    {
      public Thread newThread(Runnable r)
      {
        String name = "JavaScript Job Thread " + JavaScriptJobManagerImpl.NEXT_THREAD_ID.getAndIncrement();
        executorThread_ = new Thread(r, name);
        executorThread_.setDaemon(true);
        executorThread_.setPriority(JavaScriptJobManagerImpl.PRIORITY);
        return executorThread_;
      }
    });
  }
  
  public int getJobCount()
  {
    if (executor_.isShutdown()) {
      return 0;
    }
    int count1 = Integer.MIN_VALUE;
    int count2 = Integer.MAX_VALUE;
    while (count1 != count2)
    {
      count1 = getJobCountInner();
      sleep(10L);
      count2 = getJobCountInner();
    }
    return count1;
  }
  
  private synchronized int getJobCountInner()
  {
    executor_.purge();
    return (int)(executor_.getTaskCount() - executor_.getCompletedTaskCount());
  }
  
  public synchronized int addJob(JavaScriptJob job, Page page)
  {
    WebWindow w = getWindow();
    if (w == null) {
      return 0;
    }
    if (w.getEnclosedPage() != page) {
      return 0;
    }
    int id = NEXT_JOB_ID.getAndIncrement();
    job.setId(Integer.valueOf(id));
    
    ExecutingJobTracker jobWrapper = new ExecutingJobTracker(job);
    ScheduledFuture<?> future;
    ScheduledFuture<?> future;
    if (job.isPeriodic()) {
      future = executor_.scheduleAtFixedRate(jobWrapper, job.getInitialDelay(), job.getPeriod().intValue(), TimeUnit.MILLISECONDS);
    } else {
      future = executor_.schedule(jobWrapper, job.getInitialDelay(), TimeUnit.MILLISECONDS);
    }
    futures_.put(Integer.valueOf(id), future);
    LOG.debug("Added job: " + job + ".");
    return id;
  }
  
  public synchronized void removeJob(int id)
  {
    ScheduledFuture<?> future = (ScheduledFuture)futures_.remove(Integer.valueOf(id));
    if (future != null)
    {
      LOG.debug("Removing job " + id + ".");
      future.cancel(false);
      LOG.debug("Removed job " + id + ".");
    }
  }
  
  public synchronized void stopJob(int id)
  {
    Future<?> future = (Future)futures_.remove(Integer.valueOf(id));
    if (future != null)
    {
      LOG.debug("Stopping job " + id + ".");
      future.cancel(true);
      LOG.debug("Stopped job " + id + ".");
    }
  }
  
  public synchronized void removeAllJobs()
  {
    LOG.debug("Removing all jobs.");
    int count = 0;
    for (Future<?> future : futures_.values())
    {
      future.cancel(false);
      count++;
    }
    futures_.clear();
    if (count > 0) {
      LOG.debug("Removed all jobs (" + count + ").");
    }
  }
  
  public int waitForJobs(long timeoutMillis)
  {
    LOG.debug("Waiting for all jobs to finish (will wait max " + timeoutMillis + " millis).");
    if (timeoutMillis > 0L)
    {
      long start = System.currentTimeMillis();
      long interval = Math.min(timeoutMillis, 100L);
      while ((getJobCount() > 0) && (System.currentTimeMillis() - start < timeoutMillis)) {
        sleep(interval);
      }
    }
    int jobs = getJobCount();
    LOG.debug("Finished waiting for all jobs to finish (final job count is " + jobs + ").");
    return jobs;
  }
  
  public int waitForJobsStartingBefore(long delayMillis)
  {
    LOG.debug("Waiting for all jobs to finish that start within " + delayMillis + " millis.");
    long maxStartTime = System.currentTimeMillis() + delayMillis;
    try
    {
      ScheduledFuture<?> lastJobWithinDelay = getLastJobStartingBefore(maxStartTime);
      if (lastJobWithinDelay == null)
      {
        waitForCurrentlyRunningJobs();
        lastJobWithinDelay = getLastJobStartingBefore(maxStartTime);
      }
      while (lastJobWithinDelay != null)
      {
        waitForCompletion(lastJobWithinDelay);
        waitForCurrentlyRunningJobs();
        lastJobWithinDelay = getLastJobStartingBefore(maxStartTime);
      }
    }
    catch (InterruptedException e)
    {
      throw new RuntimeException(e);
    }
    int jobs = getJobCount();
    LOG.debug("Finished waiting for all jobs to finish (final job count is " + jobs + ").");
    return jobs;
  }
  
  private void waitForCurrentlyRunningJobs()
    throws InterruptedException
  {
    synchronized (currentlyRunningJobs_)
    {
      while (!currentlyRunningJobs_.isEmpty())
      {
        JavaScriptJob job = (JavaScriptJob)currentlyRunningJobs_.get(0);
        while (currentlyRunningJobs_.contains(job)) {
          currentlyRunningJobs_.wait();
        }
      }
    }
  }
  
  private synchronized ScheduledFuture<?> getLastJobStartingBefore(long maxStartTime)
  {
    long currentDelay = Long.MIN_VALUE;
    ScheduledFuture<?> job = null;
    long maxAllowedDelay = maxStartTime - System.currentTimeMillis();
    for (ScheduledFuture<?> future : futures_.values())
    {
      long delay = future.getDelay(TimeUnit.MILLISECONDS);
      if ((!future.isDone()) && (delay > currentDelay) && ((delay < maxAllowedDelay) || (delay <= 0L)))
      {
        currentDelay = delay;
        job = future;
      }
    }
    LOG.debug("Last job starting before " + maxStartTime + ": " + job + ".");
    return job;
  }
  
  private boolean waitForCompletion(ScheduledFuture<?> job)
  {
    try
    {
      long delay = job.getDelay(TimeUnit.MILLISECONDS);
      LOG.debug("Waiting for completion of job starting in " + delay + "ms: " + job);
      
      job.get(delay + 100L, TimeUnit.MILLISECONDS);
      LOG.debug("Job done: " + job.isDone() + ".");
    }
    catch (CancellationException e)
    {
      LOG.debug("Job cancelled: " + job + ".");
      return false;
    }
    catch (InterruptedException e)
    {
      LOG.debug(e.getMessage(), e);
      return false;
    }
    catch (ExecutionException e)
    {
      LOG.debug(e.getMessage(), e);
      return false;
    }
    catch (TimeoutException e)
    {
      return false;
    }
    return true;
  }
  
  public synchronized void shutdown()
  {
    executor_.purge();
    List<Runnable> neverStartedTasks = executor_.shutdownNow();
    futures_.clear();
    if (executorThread_ != null)
    {
      try
      {
        executorThread_.join(5000L);
      }
      catch (InterruptedException e) {}
      if (executorThread_.isAlive()) {
        LOG.warn("Executor thread " + executorThread_.getName() + " still alive");
      }
    }
    if (getJobCount() - neverStartedTasks.size() > 0) {
      LOG.warn("jobCount: " + getJobCount() + "(taskCount: " + executor_.getTaskCount() + ", completedTaskCount: " + executor_.getCompletedTaskCount() + ", never started tasks: " + neverStartedTasks.size() + ")");
    }
  }
  
  private WebWindow getWindow()
  {
    return (WebWindow)window_.get();
  }
  
  private void sleep(long millis)
  {
    try
    {
      Thread.sleep(millis);
    }
    catch (InterruptedException e) {}
  }
  
  private void writeObject(ObjectOutputStream out)
    throws IOException
  {
    out.writeObject(window_.get());
  }
  
  private void readObject(ObjectInputStream in)
    throws IOException, ClassNotFoundException
  {
    WebWindow window = (WebWindow)in.readObject();
    init(window);
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript.background;

import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class JavaScriptStringJob
  extends JavaScriptExecutionJob
{
  private final String script_;
  
  public JavaScriptStringJob(int initialDelay, Integer period, String label, WebWindow window, String script)
  {
    super(initialDelay, period, label, window);
    script_ = script;
  }
  
  protected void runJavaScript(HtmlPage page)
  {
    if (script_ == null) {
      return;
    }
    page.executeJavaScriptIfPossible(script_, "JavaScriptStringJob", 1);
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.background.JavaScriptStringJob
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.WebWindow;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import org.apache.commons.logging.Log;

class JavaScriptEngine$1
  implements ContextAction
{
  JavaScriptEngine$1(JavaScriptEngine paramJavaScriptEngine, WebWindow paramWebWindow) {}
  
  public Object run(Context cx)
  {
    try
    {
      JavaScriptEngine.access$000(this$0, val$webWindow, cx);
    }
    catch (Exception e)
    {
      JavaScriptEngine.access$100().error("Exception while initializing JavaScript for the page", e);
      throw new ScriptException(null, e);
    }
    return null;
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.1
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;

class JavaScriptEngine$2
  extends JavaScriptEngine.HtmlUnitContextAction
{
  JavaScriptEngine$2(JavaScriptEngine paramJavaScriptEngine, Scriptable x0, HtmlPage x1, String paramString1, String paramString2, int paramInt)
  {
    super(paramJavaScriptEngine, x0, x1);
  }
  
  public Object doRun(Context cx)
  {
    return cx.compileString(val$source, val$sourceName, val$startLine, null);
  }
  
  protected String getSourceCode(Context cx)
  {
    return val$source;
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.2
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Script;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;

class JavaScriptEngine$3
  extends JavaScriptEngine.HtmlUnitContextAction
{
  JavaScriptEngine$3(JavaScriptEngine paramJavaScriptEngine, Scriptable x0, HtmlPage x1, Script paramScript, Scriptable paramScriptable1)
  {
    super(paramJavaScriptEngine, x0, x1);
  }
  
  public Object doRun(Context cx)
  {
    return val$script.exec(cx, val$scope);
  }
  
  protected String getSourceCode(Context cx)
  {
    return null;
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.3
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;

class JavaScriptEngine$4
  extends JavaScriptEngine.HtmlUnitContextAction
{
  JavaScriptEngine$4(JavaScriptEngine paramJavaScriptEngine, Scriptable x0, HtmlPage x1, HtmlPage paramHtmlPage1, Function paramFunction, Scriptable paramScriptable1, Object paramObject, Object[] paramArrayOfObject)
  {
    super(paramJavaScriptEngine, x0, x1);
  }
  
  public Object doRun(Context cx)
  {
    return this$0.callFunction(val$htmlPage, val$function, cx, val$scope, (Scriptable)val$thisObject, val$args);
  }
  
  protected String getSourceCode(Context cx)
  {
    return cx.decompileFunction(val$function, 2);
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.4
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;

abstract class JavaScriptEngine$HtmlUnitContextAction
  implements ContextAction
{
  private final Scriptable scope_;
  private final HtmlPage htmlPage_;
  
  public JavaScriptEngine$HtmlUnitContextAction(JavaScriptEngine paramJavaScriptEngine, Scriptable scope, HtmlPage htmlPage)
  {
    scope_ = scope;
    htmlPage_ = htmlPage;
  }
  
  /* Error */
  public final Object run(Context cx)
  {
    // Byte code:
    //   0: aload_0
    //   1: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   4: invokestatic 5	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$300	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)Ljava/lang/ThreadLocal;
    //   7: invokevirtual 6	java/lang/ThreadLocal:get	()Ljava/lang/Object;
    //   10: checkcast 7	java/lang/Boolean
    //   13: astore_2
    //   14: aload_0
    //   15: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   18: invokestatic 5	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$300	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)Ljava/lang/ThreadLocal;
    //   21: getstatic 8	java/lang/Boolean:TRUE	Ljava/lang/Boolean;
    //   24: invokevirtual 9	java/lang/ThreadLocal:set	(Ljava/lang/Object;)V
    //   27: aload_1
    //   28: ldc 10
    //   30: aload_0
    //   31: getfield 3	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:scope_	Lnet/sourceforge/htmlunit/corejs/javascript/Scriptable;
    //   34: invokevirtual 11	net/sourceforge/htmlunit/corejs/javascript/Context:putThreadLocal	(Ljava/lang/Object;Ljava/lang/Object;)V
    //   37: aload_1
    //   38: ldc 12
    //   40: aload_0
    //   41: getfield 4	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:htmlPage_	Lcom/gargoylesoftware/htmlunit/html/HtmlPage;
    //   44: invokevirtual 11	net/sourceforge/htmlunit/corejs/javascript/Context:putThreadLocal	(Ljava/lang/Object;Ljava/lang/Object;)V
    //   47: aload_0
    //   48: getfield 4	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:htmlPage_	Lcom/gargoylesoftware/htmlunit/html/HtmlPage;
    //   51: dup
    //   52: astore_3
    //   53: monitorenter
    //   54: aload_0
    //   55: aload_1
    //   56: invokevirtual 13	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:doRun	(Lnet/sourceforge/htmlunit/corejs/javascript/Context;)Ljava/lang/Object;
    //   59: astore 4
    //   61: aload_0
    //   62: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   65: invokestatic 14	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$400	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)V
    //   68: aload 4
    //   70: astore 5
    //   72: aload_3
    //   73: monitorexit
    //   74: aload_0
    //   75: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   78: invokestatic 5	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$300	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)Ljava/lang/ThreadLocal;
    //   81: aload_2
    //   82: invokevirtual 9	java/lang/ThreadLocal:set	(Ljava/lang/Object;)V
    //   85: aload 5
    //   87: areturn
    //   88: astore 6
    //   90: aload_3
    //   91: monitorexit
    //   92: aload 6
    //   94: athrow
    //   95: astore_3
    //   96: aload_0
    //   97: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   100: new 16	com/gargoylesoftware/htmlunit/ScriptException
    //   103: dup
    //   104: aload_0
    //   105: getfield 4	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:htmlPage_	Lcom/gargoylesoftware/htmlunit/html/HtmlPage;
    //   108: aload_3
    //   109: aload_0
    //   110: aload_1
    //   111: invokevirtual 17	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:getSourceCode	(Lnet/sourceforge/htmlunit/corejs/javascript/Context;)Ljava/lang/String;
    //   114: invokespecial 18	com/gargoylesoftware/htmlunit/ScriptException:<init>	(Lcom/gargoylesoftware/htmlunit/html/HtmlPage;Ljava/lang/Throwable;Ljava/lang/String;)V
    //   117: invokevirtual 19	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:handleJavaScriptException	(Lcom/gargoylesoftware/htmlunit/ScriptException;)V
    //   120: aconst_null
    //   121: astore 4
    //   123: aload_0
    //   124: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   127: invokestatic 5	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$300	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)Ljava/lang/ThreadLocal;
    //   130: aload_2
    //   131: invokevirtual 9	java/lang/ThreadLocal:set	(Ljava/lang/Object;)V
    //   134: aload 4
    //   136: areturn
    //   137: astore_3
    //   138: aload_0
    //   139: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   142: invokevirtual 21	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:getWebClient	()Lcom/gargoylesoftware/htmlunit/WebClient;
    //   145: invokevirtual 22	com/gargoylesoftware/htmlunit/WebClient:isThrowExceptionOnScriptError	()Z
    //   148: ifeq +12 -> 160
    //   151: new 23	java/lang/RuntimeException
    //   154: dup
    //   155: aload_3
    //   156: invokespecial 24	java/lang/RuntimeException:<init>	(Ljava/lang/Throwable;)V
    //   159: athrow
    //   160: invokestatic 25	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$100	()Lorg/apache/commons/logging/Log;
    //   163: ldc 26
    //   165: aload_3
    //   166: invokeinterface 27 3 0
    //   171: aconst_null
    //   172: astore 4
    //   174: aload_0
    //   175: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   178: invokestatic 5	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$300	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)Ljava/lang/ThreadLocal;
    //   181: aload_2
    //   182: invokevirtual 9	java/lang/ThreadLocal:set	(Ljava/lang/Object;)V
    //   185: aload 4
    //   187: areturn
    //   188: astore 7
    //   190: aload_0
    //   191: getfield 1	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine$HtmlUnitContextAction:this$0	Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;
    //   194: invokestatic 5	com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine:access$300	(Lcom/gargoylesoftware/htmlunit/javascript/JavaScriptEngine;)Ljava/lang/ThreadLocal;
    //   197: aload_2
    //   198: invokevirtual 9	java/lang/ThreadLocal:set	(Ljava/lang/Object;)V
    //   201: aload 7
    //   203: athrow
    // Line number table:
    //   Java source line #514	-> byte code offset #0
    //   Java source line #515	-> byte code offset #14
    //   Java source line #518	-> byte code offset #27
    //   Java source line #519	-> byte code offset #37
    //   Java source line #520	-> byte code offset #47
    //   Java source line #521	-> byte code offset #54
    //   Java source line #522	-> byte code offset #61
    //   Java source line #523	-> byte code offset #68
    //   Java source line #538	-> byte code offset #74
    //   Java source line #524	-> byte code offset #88
    //   Java source line #526	-> byte code offset #95
    //   Java source line #527	-> byte code offset #96
    //   Java source line #528	-> byte code offset #120
    //   Java source line #538	-> byte code offset #123
    //   Java source line #530	-> byte code offset #137
    //   Java source line #531	-> byte code offset #138
    //   Java source line #532	-> byte code offset #151
    //   Java source line #534	-> byte code offset #160
    //   Java source line #535	-> byte code offset #171
    //   Java source line #538	-> byte code offset #174
    // Local variable table:
    //   start	length	slot	name	signature
    //   0	204	0	this	HtmlUnitContextAction
    //   0	204	1	cx	Context
    //   13	185	2	javaScriptAlreadyRunning	Boolean
    //   95	14	3	e	Exception
    //   137	29	3	e	TimeoutError
    //   59	127	4	response	Object
    //   70	16	5	localObject1	Object
    //   88	5	6	localObject2	Object
    //   188	14	7	localObject3	Object
    // Exception table:
    //   from	to	target	type
    //   54	74	88	finally
    //   88	92	88	finally
    //   27	74	95	java/lang/Exception
    //   88	95	95	java/lang/Exception
    //   27	74	137	com/gargoylesoftware/htmlunit/javascript/TimeoutError
    //   88	95	137	com/gargoylesoftware/htmlunit/javascript/TimeoutError
    //   27	74	188	finally
    //   88	123	188	finally
    //   137	174	188	finally
    //   188	190	188	finally
  }
  
  protected abstract Object doRun(Context paramContext);
  
  protected abstract String getSourceCode(Context paramContext);
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.HtmlUnitContextAction
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;

class JavaScriptEngine$FallbackCaller
  extends ScriptableObject
{
  private static final long serialVersionUID = -7124423159070941606L;
  
  public Object get(String name, Scriptable start)
  {
    if ((start instanceof ScriptableWithFallbackGetter)) {
      return ((ScriptableWithFallbackGetter)start).getWithFallback(name);
    }
    return NOT_FOUND;
  }
  
  public String getClassName()
  {
    return "htmlUnitHelper-fallbackCaller";
  }
}

/* Location:
 * Qualified Name:     com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.FallbackCaller
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package com.gargoylesoftware.htmlunit.javascript;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.configuration.ClassConfiguration;
import com.gargoylesoftware.htmlunit.javascript.configuration.JavaScriptConfiguration;
import com.gargoylesoftware.htmlunit.javascript.host.Element;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.FunctionObject;
import net.sourceforge.htmlunit.corejs.javascript.Script;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JavaScriptEngine
{
  private static final long serialVersionUID = -5414040051465432088L;
  private static final Log LOG = LogFactory.getLog(JavaScriptEngine.class);
  private final WebClient webClient_;
  private final HtmlUnitContextFactory contextFactory_;
  private transient ThreadLocal<Boolean> javaScriptRunning_;
  private transient ThreadLocal<List<PostponedAction>> postponedActions_;
  private transient ThreadLocal<Boolean> holdPostponedActions_;
  public static final String KEY_STARTING_SCOPE = "startingScope";
  public static final String KEY_STARTING_PAGE = "startingPage";
  
  public JavaScriptEngine(WebClient webClient)
  {
    webClient_ = webClient;
    contextFactory_ = new HtmlUnitContextFactory(webClient);
    initTransientFields();
  }
  
  public final WebClient getWebClient()
  {
    return webClient_;
  }
  
  public HtmlUnitContextFactory getContextFactory()
  {
    return contextFactory_;
  }
  
  public void initialize(final WebWindow webWindow)
  {
    WebAssert.notNull("webWindow", webWindow);
    
    ContextAction action = new ContextAction()
    {
      public Object run(Context cx)
      {
        try
        {
          JavaScriptEngine.this.init(webWindow, cx);
        }
        catch (Exception e)
        {
          JavaScriptEngine.LOG.error("Exception while initializing JavaScript for the page", e);
          throw new ScriptException(null, e);
        }
        return null;
      }
    };
    getContextFactory().call(action);
  }
  
  private void init(WebWindow webWindow, Context context)
    throws Exception
  {
    WebClient webClient = webWindow.getWebClient();
    Map<Class<? extends SimpleScriptable>, Scriptable> prototypes = new HashMap();
    
    Map<String, Scriptable> prototypesPerJSName = new HashMap();
    Window window = new Window();
    JavaScriptConfiguration jsConfig = JavaScriptConfiguration.getInstance(webClient.getBrowserVersion());
    context.initStandardObjects(window);
    
    deleteProperties(window, new String[] { "javax", "org", "com", "edu", "net", "JavaAdapter", "JavaImporter", "Continuation" });
    if (webClient.getBrowserVersion().isIE()) {
      deleteProperties(window, new String[] { "Packages", "java", "getClass", "XML", "XMLList", "Namespace", "QName" });
    }
    Scriptable fallbackCaller = new FallbackCaller(null);
    ScriptableObject.getObjectPrototype(window).setPrototype(fallbackCaller);
    for (String jsClassName : jsConfig.keySet())
    {
      ClassConfiguration config = jsConfig.getClassConfiguration(jsClassName);
      boolean isWindow = Window.class.getName().equals(config.getLinkedClass().getName());
      if (isWindow)
      {
        configureConstantsPropertiesAndFunctions(config, window);
      }
      else
      {
        ScriptableObject prototype = configureClass(config, window);
        if (config.isJsObject())
        {
          if (!getWebClient().getBrowserVersion().isIE())
          {
            SimpleScriptable obj = (SimpleScriptable)config.getLinkedClass().newInstance();
            prototype.defineProperty("__proto__", prototype, 2);
            obj.defineProperty("prototype", prototype, 2);
            obj.setParentScope(window);
            ScriptableObject.defineProperty(window, config.getClassName(), obj, 2);
            
            configureConstants(config, obj);
            if ((obj.getClass() == Element.class) && ((webWindow.getEnclosedPage() instanceof HtmlPage)))
            {
              DomNode domNode = new HtmlDivision(null, "", (SgmlPage)webWindow.getEnclosedPage(), null);
              
              obj.setDomNode(domNode);
            }
          }
          prototypes.put(config.getLinkedClass(), prototype);
        }
        prototypesPerJSName.put(config.getClassName(), prototype);
      }
    }
    Scriptable objectPrototype = ScriptableObject.getObjectPrototype(window);
    for (Map.Entry<String, Scriptable> entry : prototypesPerJSName.entrySet())
    {
      String name = (String)entry.getKey();
      ClassConfiguration config = jsConfig.getClassConfiguration(name);
      Scriptable prototype = (Scriptable)entry.getValue();
      if (prototype.getPrototype() != null) {
        prototype = prototype.getPrototype();
      }
      if (!StringUtils.isEmpty(config.getExtendedClass()))
      {
        Scriptable parentPrototype = (Scriptable)prototypesPerJSName.get(config.getExtendedClass());
        prototype.setPrototype(parentPrototype);
      }
      else
      {
        prototype.setPrototype(objectPrototype);
      }
    }
    Class<?>[] evalFnTypes = { String.class };
    Member evalFn = Window.class.getMethod("custom_eval", evalFnTypes);
    FunctionObject jsCustomEval = new FunctionObject("eval", evalFn, window);
    window.associateValue("custom_eval", jsCustomEval);
    for (String jsClassName : jsConfig.keySet())
    {
      ClassConfiguration config = jsConfig.getClassConfiguration(jsClassName);
      Method jsConstructor = config.getJsConstructor();
      if (jsConstructor != null)
      {
        Scriptable prototype = (Scriptable)prototypesPerJSName.get(jsClassName);
        if (prototype != null)
        {
          FunctionObject jsCtor = new FunctionObject(jsClassName, jsConstructor, window);
          jsCtor.addAsConstructor(window, prototype);
        }
      }
    }
    removePrototypeProperties(window, "String", new String[] { "equals", "equalsIgnoreCase", "trim" });
    removePrototypeProperties(window, "Function", new String[] { "bind" });
    removePrototypeProperties(window, "Date", new String[] { "toISOString", "toJSON" });
    if (webClient.getBrowserVersion().isIE())
    {
      deleteProperties(window, new String[] { "isXMLName", "uneval" });
      removePrototypeProperties(window, "Object", new String[] { "__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", "toSource" });
      
      removePrototypeProperties(window, "Array", new String[] { "every", "filter", "forEach", "indexOf", "lastIndexOf", "map", "reduce", "reduceRight", "some", "toSource" });
      
      removePrototypeProperties(window, "Date", new String[] { "toSource" });
      removePrototypeProperties(window, "Function", new String[] { "toSource" });
      removePrototypeProperties(window, "Number", new String[] { "toSource" });
      removePrototypeProperties(window, "String", new String[] { "toSource" });
    }
    else if ("FF2".equals(webClient.getBrowserVersion().getNickname()))
    {
      removePrototypeProperties(window, "Array", new String[] { "reduce", "reduceRight" });
    }
    window.setPrototypes(prototypes);
    window.initialize(webWindow);
  }
  
  private void deleteP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd