package fitnesse.components;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;


/**
 * Update the current thread class path with jars foundin a "plugins" directory.
 */
public class PluginsClassLoader {

  public static ClassLoader getClassLoader(String rootPath) throws Exception {
    ClassLoader result = ClassLoader.getSystemClassLoader();
    File pluginsDirectory = new File(rootPath, "plugins");

    URL[] urls = urlsForPlugins(pluginsDirectory);
    if (urls.length > 0) {
      result = new URLClassLoader(urls, result);
    }
    return result;
  }

  private static URL[] urlsForPlugins(File pluginsDirectory) throws Exception {
    List<URL> urls = new ArrayList<>();

    if (pluginsDirectory.exists() && pluginsDirectory.isDirectory())
      for (File plugin : pluginsDirectory.listFiles())
        if (plugin.getName().endsWith("jar"))
          urls.addAll(toUrls(plugin.getCanonicalPath()));

    return urls.toArray(new URL[urls.size()]);
  }

  private static List<URL> toUrls(String classpathItems) throws Exception {
    final String separator = File.pathSeparator;
    String currentClassPath = System.getProperty("java.class.path");
    System.setProperty("java.class.path", currentClassPath + separator + classpathItems);
    String[] items = classpathItems.split(separator);
    List<URL> urls = new ArrayList<>(items.length);

    for (String item : items) {
      urls.add(toUrl(item));
    }
    return urls;
  }

  private static URL toUrl(String fileName) throws MalformedURLException {
    return new File(fileName).toURI().toURL();
  }
}

@@ -60,27 +60,22 @@
 ava.
-lang.reflect.Method
+io.IOException
 ;%0Aim
@@ -228,33 +228,45 @@
 %0A * 
-Update the current thread
+Gets a class loader which extends the
  cla
@@ -292,13 +292,12 @@
 ound
+ 
 in 
-a 
 %22plu
@@ -411,32 +411,34 @@
 ootPath) throws 
+IO
 Exception %7B%0A    
@@ -562,34 +562,40 @@
     
-URL%5B%5D urls = urlsForP
+List%3CString%3E plugins = p
 lugin
+Jar
 s(pl
@@ -623,26 +623,73 @@
 if (
-urls.length %3E 0) %7B
+!plugins.isEmpty()) %7B%0A      URL%5B%5D urls = urlsForPlugins(plugins);
 %0A   
@@ -734,16 +734,65 @@
 esult);%0A
+      appendPluginsToClassPathProperty(plugins);%0A
     %7D%0A  
@@ -834,27 +834,30 @@
 tic 
-URL%5B%5D urlsForP
+List%3CString%3E p
 lugin
+Jar
 s(Fi
@@ -876,32 +876,34 @@
 rectory) throws 
+IO
 Exception %7B%0A    
@@ -903,33 +903,38 @@
  %7B%0A    List%3C
-URL%3E urls
+String%3E result
  = new Array
@@ -943,17 +943,16 @@
 st%3C%3E();%0A
-%0A
     if (
@@ -1011,16 +1011,18 @@
 ctory())
+ %7B
 %0A      f
@@ -1068,16 +1068,18 @@
 Files())
+ %7B
 %0A       
@@ -1116,16 +1116,18 @@
 (%22jar%22))
+ %7B
 %0A       
@@ -1133,26 +1133,18 @@
     
-urls.addAll(toUrls
+result.add
 (plu
@@ -1170,522 +1170,291 @@
 h())
-)
 ;%0A
-%0A    return urls.toArray(new URL%5Burls.size()%5D);%0A  %7D%0A%0A  private static List%3CURL%3E toUrls(String classpathItems) throws Exception %7B%0A    final String separator = File.pathSeparator;%0A    String currentClassPath = System.getProperty(%22java.class.path%22);%0A    System.setProperty(%22java.class.path%22, currentClassPath + separator + classpathItems);%0A    String%5B%5D items = classpathItems.split(separator);%0A    List%3CURL%3E urls = new ArrayList%3C%3E(items.length);%0A%0A    for (String item : items) %7B%0A      urls.add(toUrl(item))
+        %7D%0A      %7D%0A    %7D%0A    return result;%0A  %7D%0A%0A  private static URL%5B%5D urlsForPlugins(List%3CString%3E plugins) throws MalformedURLException %7B%0A    URL%5B%5D urls = new URL%5Bplugins.size()%5D;%0A%0A    int i = 0;%0A    for (String plugin : plugins) %7B%0A      urls%5Bi%5D = toUrl(plugin);%0A      i++
 ;%0A    %7D%0A
     
@@ -1441,32 +1441,33 @@
      i++;%0A    %7D%0A
+%0A
     return urls;
@@ -1597,11 +1597,464 @@
 L();%0A  %7D
+%0A%0A  private static void appendPluginsToClassPathProperty(List%3CString%3E plugins) %7B%0A    String currentClassPath = System.getProperty(%22java.class.path%22);%0A%0A    StringBuilder classpathItems = new StringBuilder();%0A    classpathItems.append(currentClassPath);%0A    for (String plugin : plugins) %7B%0A      classpathItems.append(File.pathSeparator);%0A      classpathItems.append(plugin);%0A    %7D%0A    System.setProperty(%22java.class.path%22, classpathItems.toString());%0A  %7D
 %0A%7D%0A

Restructure plugins class loader