[jboss-svn-commits] JBoss Common SVN: r4712 - shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jul 9 15:26:43 EDT 2010


Author: ALRubinger
Date: 2010-07-09 15:26:43 -0400 (Fri, 09 Jul 2010)
New Revision: 4712

Added:
   shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ImmediateScheduledExecutorService.java
Modified:
   shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java
Log:
[SHRINKWRAP-161] Obtain a scheduled service or make a new one for mouting

Added: shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ImmediateScheduledExecutorService.java
===================================================================
--- shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ImmediateScheduledExecutorService.java	                        (rev 0)
+++ shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ImmediateScheduledExecutorService.java	2010-07-09 19:26:43 UTC (rev 4712)
@@ -0,0 +1,240 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * 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 org.jboss.shrinkwrap.classloader;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * {@link ScheduledExecutorService} implementation which ignores
+ * all scheduling operations and immediately dispatches invocations
+ * to an underlying {@link ExecutorService}
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ */
+class ImmediateScheduledExecutorService implements ScheduledExecutorService
+{
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Delegate for all operations
+    */
+   private final ExecutorService delegate;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructors -----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new instance using the specified delegate
+    * @param delegate
+    * @throws IllegalArgumentException If the delegate is not specified
+    */
+   ImmediateScheduledExecutorService(final ExecutorService delegate) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (delegate == null)
+      {
+         throw new IllegalArgumentException("Delegate " + ExecutorService.class.getSimpleName() + " must be specified");
+      }
+
+      // Set
+      this.delegate = delegate;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static class ImmediateScheduledFuture<V> implements ScheduledFuture<V>
+   {
+
+      /**
+       * Delegate through which all {@link Future} contracts will
+       * be fulfilled 
+       */
+      private final Future<V> delegate;
+
+      ImmediateScheduledFuture(final Future<V> delegate)
+      {
+         assert delegate != null : "Delegate Future must be specified";
+         this.delegate = delegate;
+      }
+
+      /**
+       * Returns a delay of 0, always
+       * @see java.util.concurrent.Delayed#getDelay(java.util.concurrent.TimeUnit)
+       */
+      public long getDelay(final TimeUnit unit)
+      {
+         // No delay
+         return 0;
+      }
+
+      /**
+       * Compare our delay of 0 to the incoming {@link Delayed}
+       * @see java.lang.Comparable#compareTo(java.lang.Object)
+       */
+      public int compareTo(final Delayed o)
+      {
+         final TimeUnit unit = TimeUnit.SECONDS;
+         return new Long(this.getDelay(unit)).compareTo(o.getDelay(unit));
+      }
+
+      /*
+       * Delegate methods only below this marker
+       */
+
+      public boolean cancel(boolean mayInterruptIfRunning)
+      {
+         return delegate.cancel(mayInterruptIfRunning);
+      }
+
+      public V get() throws InterruptedException, ExecutionException
+      {
+         try
+         {
+            return this.delegate.get();
+         }
+         catch (final Exception e)
+         {
+            throw new ExecutionException(e);
+         }
+      }
+
+      public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
+      {
+         return get();
+      }
+
+      public boolean isCancelled()
+      {
+         return this.delegate.isCancelled();
+      }
+
+      public boolean isDone()
+      {
+         return this.delegate.isDone();
+      }
+
+   }
+
+   @SuppressWarnings("unchecked")
+   public ScheduledFuture<?> schedule(final Runnable command, final long delay, final TimeUnit unit)
+   {
+      final Future<?> future = this.submit(command);
+      return new ImmediateScheduledFuture(future);
+   }
+
+   public <V> ScheduledFuture<V> schedule(final Callable<V> callable, final long delay, final TimeUnit unit)
+   {
+      final Future<V> future = this.submit(callable);
+      return new ImmediateScheduledFuture<V>(future);
+   }
+
+   public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
+   {
+      return this.schedule(command, period, unit);
+   }
+
+   public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
+   {
+      return this.schedule(command, delay, unit);
+   }
+
+   /*
+    * Everything below this marker simply passes control along to the delegate
+    */
+
+   public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
+   {
+      return delegate.awaitTermination(timeout, unit);
+   }
+
+   public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException
+   {
+      return delegate.invokeAll(tasks);
+   }
+
+   public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
+         throws InterruptedException
+   {
+      return delegate.invokeAll(tasks, timeout, unit);
+   }
+
+   public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException
+   {
+      return delegate.invokeAny(tasks);
+   }
+
+   public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
+         throws InterruptedException, ExecutionException, TimeoutException
+   {
+      return delegate.invokeAny(tasks, timeout, unit);
+   }
+
+   public boolean isShutdown()
+   {
+      return delegate.isShutdown();
+   }
+
+   public boolean isTerminated()
+   {
+      return delegate.isTerminated();
+   }
+
+   public void shutdown()
+   {
+      delegate.shutdown();
+   }
+
+   public List<Runnable> shutdownNow()
+   {
+      return delegate.shutdownNow();
+   }
+
+   public <T> Future<T> submit(Callable<T> task)
+   {
+      return delegate.submit(task);
+   }
+
+   public Future<?> submit(Runnable task)
+   {
+      return delegate.submit(task);
+   }
+
+   public <T> Future<T> submit(Runnable task, T result)
+   {
+      return delegate.submit(task, result);
+   }
+
+   public void execute(Runnable command)
+   {
+      delegate.execute(command);
+   }
+}

Modified: shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java
===================================================================
--- shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java	2010-07-09 16:17:16 UTC (rev 4711)
+++ shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java	2010-07-09 19:26:43 UTC (rev 4712)
@@ -28,7 +28,10 @@
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.logging.Logger;
 
+import org.jboss.logmanager.Level;
 import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Configuration;
+import org.jboss.shrinkwrap.spi.Configurable;
 import org.jboss.shrinkwrap.vfs3.ArchiveFileSystem;
 import org.jboss.vfs.TempDir;
 import org.jboss.vfs.TempFileProvider;
@@ -78,11 +81,14 @@
     * be searched in the order specified for classes and resources after
     * first searching in the parent class loader.
     * 
+    * @param service {@link ScheduledExecutorService} used internally to handle mounting
+    *   of the {@link Archive}s such that they may be read
     * @param archives the {@link Archive}s from which to load classes and resources
     */
-   public ShrinkWrapClassLoader(final Archive<?>... archives)
+   public ShrinkWrapClassLoader(final ScheduledExecutorService service, final Archive<?>... archives)
    {
-      super(new URL[]{});
+      super(new URL[]
+      {});
 
       if (archives == null)
       {
@@ -101,7 +107,8 @@
     */
    public ShrinkWrapClassLoader(final ClassLoader parent, final Archive<?>... archives)
    {
-      super(new URL[]{}, parent);
+      super(new URL[]
+      {}, parent);
 
       if (archives == null)
       {
@@ -120,23 +127,44 @@
 
    private void addArchive(final Archive<?> archive)
    {
-      // TODO: Wrap a ExecutorService in a ScheduledExecutorService 
-      //Configuration configuration = archive.as(Configurable.class).getConfiguration();
-      ScheduledExecutorService executorService = null; //configuration.getExecutorService();
-      if (executorService == null)
+      // Grab or make a ScheduledExecutorService to back the mounting process
+      final Configuration configuration = archive.as(Configurable.class).getConfiguration();
+      final ExecutorService executorServiceFromArchiveConfig = configuration.getExecutorService();
+      ScheduledExecutorService scheduledService;
+      if (executorServiceFromArchiveConfig != null)
       {
-         executorService = Executors.newScheduledThreadPool(2);
-
-         // TODO: only add to 'managed' executor services if it was created here..
-
-         // add to list of resources to cleanup during close()
-         executorServicesToShutdown.add(executorService);
+         if (executorServiceFromArchiveConfig instanceof ScheduledExecutorService)
+         {
+            scheduledService = (ScheduledExecutorService) executorServiceFromArchiveConfig;
+            if (log.isLoggable(Level.TRACE))
+            {
+               log.log(Level.TRACE, "Using " + scheduledService + " from archive configuration for mounting "
+                     + archive.toString());
+            }
+         }
+         else
+         {
+            scheduledService = new ImmediateScheduledExecutorService(executorServiceFromArchiveConfig);
+            if (log.isLoggable(Level.TRACE))
+            {
+               log.log(Level.TRACE, "Wrapping " + executorServiceFromArchiveConfig + " from archive as "
+                     + scheduledService + " configuration for mounting " + archive.toString());
+            }
+         }
       }
+      else
+      {
+         scheduledService = Executors.newScheduledThreadPool(2);
+         this.executorServicesToShutdown.add(scheduledService);
+         if (log.isLoggable(Level.TRACE))
+         {
+            log.log(Level.TRACE, "Created " + scheduledService + " for mounting " + archive.toString());
+         }
+      }
 
       try
       {
-         final TempFileProvider tempFileProvider = TempFileProvider.create("shrinkwrap-classloader", executorService);
-
+         final TempFileProvider tempFileProvider = TempFileProvider.create("shrinkwrap-classloader", scheduledService);
          final TempDir tempDir = tempFileProvider.createTempDir(archive.getName());
          final VirtualFile virtualFile = VFS.getChild(UUID.randomUUID().toString()).getChild(archive.getName());
 
@@ -173,7 +201,7 @@
          }
       }
       vfsHandlesToClose.clear();
-      
+
       // Shutdown all created Executor Services.
       for (final ExecutorService executorService : executorServicesToShutdown)
       {



More information about the jboss-svn-commits mailing list