]> source.dussan.org Git - pf4j.git/commitdiff
add PluginClasspath - now you can add any classes and lib directories to plugin classpath
authorDecebal Suiu <decebal.suiu@gmail.com>
Wed, 25 Sep 2013 15:31:12 +0000 (18:31 +0300)
committerDecebal Suiu <decebal.suiu@gmail.com>
Wed, 25 Sep 2013 15:31:12 +0000 (18:31 +0300)
demo/app/src/main/resources/log4j.properties
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginDescriptorFinder.java
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
pf4j/src/main/java/ro/fortsoft/pf4j/ManifestPluginDescriptorFinder.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginClasspath.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java
pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java [new file with mode: 0644]

index f2160e87f07b4d882680d28ab4861f847cf82c2c..f7663881e0eedb9052fcd0f6f9f134ecca40fdcb 100644 (file)
@@ -2,5 +2,5 @@ log4j.rootLogger=DEBUG,Console
 
 log4j.appender.Console=org.apache.log4j.ConsoleAppender
 log4j.appender.Console.layout=org.apache.log4j.PatternLayout
-log4j.appender.Console.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n
+log4j.appender.Console.layout.conversionPattern=%-5p - %-30.30c{1} - %m\n
 
index 0de63185eac03b849faca9ae91fca3253363c501..66c1936869dab23a89925102ea985305a3c6041c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Decebal Suiu
+ * Copyright 2013 Decebal Suiu
  * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
  * the License. You may obtain a copy of the License in the LICENSE file, or at:
  */
 package ro.fortsoft.pf4j;
 
-import java.lang.reflect.AnnotatedElement;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.java.sezpoz.Index;
-import net.java.sezpoz.IndexItem;
-
 /**
- * Using Sezpoz(http://sezpoz.java.net/) for extensions discovery.
+ * The default implementation for ExtensionFinder. 
+ * Now, this class it's a "link" to {@link ro.fortsoft.pf4j.SezpozExtensionFinder}.
  * 
  * @author Decebal Suiu
  */
-public class DefaultExtensionFinder implements ExtensionFinder {
+public class DefaultExtensionFinder extends SezpozExtensionFinder {
 
-       private static final Logger log = LoggerFactory.getLogger(DefaultExtensionFinder.class);
-       
-       private volatile List<IndexItem<Extension, Object>> indices;
-       private ClassLoader classLoader;
-       
        public DefaultExtensionFinder(ClassLoader classLoader) {
-               this.classLoader = classLoader;
+               super(classLoader);
        }
        
-       @Override
-       public <T> List<ExtensionWrapper<T>> find(Class<T> type) {
-               log.debug("Find extensions for {}", type);
-        List<ExtensionWrapper<T>> result = new ArrayList<ExtensionWrapper<T>>();
-               getIndices();
-//             System.out.println("indices =  "+ indices);
-               for (IndexItem<Extension, Object> item : indices) {
-            try {
-               AnnotatedElement element = item.element();
-               Class<?> extensionType = (Class<?>) element;
-               log.debug("Checking extension type {}", extensionType);
-               if (type.isAssignableFrom(extensionType)) {
-                    Object instance = item.instance();
-                    if (instance != null) {
-                               log.debug("Added extension {}", extensionType);
-                                               result.add(new ExtensionWrapper<T>(type.cast(instance), item.annotation().ordinal()));
-                    }
-                }
-            } catch (InstantiationException e) {
-               log.error(e.getMessage(), e);
-                       }
-               }
-               
-               return result;
-       }
-
-        private List<IndexItem<Extension, Object>> getIndices() {
-         if (indices == null) {
-             indices = new ArrayList<IndexItem<Extension, Object>>(); 
-             Iterator<IndexItem<Extension, Object>> it = Index.load(Extension.class, Object.class, classLoader).iterator();
-             while (it.hasNext()) {
-                indices.add(it.next());
-             }
-         }
-         
-         return indices;
-     }
-        
 }
index 3e23ff1d5757b18ad63aed83e5fd1d0e19205f7b..144fc6e40d2b373cc01d832e4e7ffa620babb53d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Decebal Suiu
+ * Copyright 2013 Decebal Suiu
  * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
  * the License. You may obtain a copy of the License in the LICENSE file, or at:
  */
 package ro.fortsoft.pf4j;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-
-import ro.fortsoft.pf4j.util.StringUtils;
-
 /**
- * Read the plugin descriptor from the manifest file.
- *
+ * The default implementation for PluginDescriptorFinder. 
+ * Now, this class it's a "link" to {@link ro.fortsoft.pf4j.ManifestPluginDescriptorFinder}.
+ * 
  * @author Decebal Suiu
  */
-public class DefaultPluginDescriptorFinder implements PluginDescriptorFinder {
-
-       @Override
-       public PluginDescriptor find(File pluginRepository) throws PluginException {
-       // TODO it's ok with classes/ ?
-        File manifestFile = new File(pluginRepository, "classes/META-INF/MANIFEST.MF");
-        if (!manifestFile.exists()) {
-            throw new PluginException("Cannot find '" + manifestFile + "' file");
-        }
-
-       FileInputStream input = null;
-               try {
-                       input = new FileInputStream(manifestFile);
-               } catch (FileNotFoundException e) {
-                       // not happening 
-               }
-               
-       Manifest manifest = null;
-        try {
-            manifest = new Manifest(input);
-        } catch (IOException e) {
-            throw new PluginException(e.getMessage(), e);
-        } finally {
-            try {
-                               input.close();
-                       } catch (IOException e) {
-                               throw new PluginException(e.getMessage(), e);
-                       }
-        } 
-        
-        PluginDescriptor pluginDescriptor = new PluginDescriptor();
-        
-        // TODO validate !!!
-        Attributes attrs = manifest.getMainAttributes();
-        String id = attrs.getValue("Plugin-Id");
-        if (StringUtils.isEmpty(id)) {
-               throw new PluginException("Plugin-Id cannot be empty");
-        }
-        pluginDescriptor.setPluginId(id);
-        
-        String clazz = attrs.getValue("Plugin-Class");
-        if (StringUtils.isEmpty(clazz)) {
-               throw new PluginException("Plugin-Class cannot be empty");
-        }
-        pluginDescriptor.setPluginClass(clazz);
-        
-        String version = attrs.getValue("Plugin-Version");
-        if (StringUtils.isEmpty(version)) {
-               throw new PluginException("Plugin-Version cannot be empty");
-        }
-        pluginDescriptor.setPluginVersion(PluginVersion.createVersion(version));
-        
-        String provider = attrs.getValue("Plugin-Provider");
-        pluginDescriptor.setProvider(provider);        
-        String dependencies = attrs.getValue("Plugin-Dependencies");
-        pluginDescriptor.setDependencies(dependencies);
+public class DefaultPluginDescriptorFinder extends ManifestPluginDescriptorFinder {
 
-               return pluginDescriptor;
+       public DefaultPluginDescriptorFinder(PluginClasspath pluginClasspath) {
+               super(pluginClasspath);
        }
        
 }
index a6c9fad84cfcf7da64ca0fa67cb1f5951316a421..1c239dc1b96081cf7e446acabbac92e8d8bbc1a8 100644 (file)
@@ -47,9 +47,11 @@ public class DefaultPluginManager implements PluginManager {
      */
     private File pluginsDirectory;
 
-    private ExtensionFinder extensionFinder;
+    private final ExtensionFinder extensionFinder;
     
-    private PluginDescriptorFinder pluginDescriptorFinder;
+    private final PluginDescriptorFinder pluginDescriptorFinder;
+    
+    private final PluginClasspath pluginClasspath;
     
     /**
      * A map of plugins this manager is responsible for (the key is the 'pluginId').
@@ -114,6 +116,7 @@ public class DefaultPluginManager implements PluginManager {
         disabledPlugins = new ArrayList<String>();
         compoundClassLoader = new CompoundClassLoader();
         
+        pluginClasspath = createPluginClasspath();
         pluginDescriptorFinder = createPluginDescriptorFinder();
         extensionFinder = createExtensionFinder();
 
@@ -278,7 +281,7 @@ public class DefaultPluginManager implements PluginManager {
         * Add the possibility to override the PluginDescriptorFinder. 
         */
     protected PluginDescriptorFinder createPluginDescriptorFinder() {
-       return new DefaultPluginDescriptorFinder();
+       return new DefaultPluginDescriptorFinder(pluginClasspath);
     }
 
     /**
@@ -288,6 +291,13 @@ public class DefaultPluginManager implements PluginManager {
        return new DefaultExtensionFinder(compoundClassLoader);
     }
 
+    /**
+     * Add the possibility to override the PluginClassPath. 
+     */
+    protected PluginClasspath createPluginClasspath() {
+       return new PluginClasspath();
+    }
+    
     protected boolean isPluginDisabled(String pluginId) {
        if (enabledPlugins.isEmpty()) {
                return disabledPlugins.contains(pluginId);
@@ -325,7 +335,7 @@ public class DefaultPluginManager implements PluginManager {
 
         // load plugin
         log.debug("Loading plugin '{}'", pluginPath);
-        PluginLoader pluginLoader = new PluginLoader(this, pluginDescriptor, pluginDirectory);
+        PluginLoader pluginLoader = new PluginLoader(this, pluginDescriptor, pluginDirectory, pluginClasspath);
         pluginLoader.load();
         log.debug("Loaded plugin '{}'", pluginPath);
         
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/ManifestPluginDescriptorFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/ManifestPluginDescriptorFinder.java
new file mode 100644 (file)
index 0000000..fd82793
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012 Decebal Suiu
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
+ * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ro.fortsoft.pf4j.util.StringUtils;
+
+/**
+ * Read the plugin descriptor from the manifest file.
+ *
+ * @author Decebal Suiu
+ */
+public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {
+
+       private static final Logger log = LoggerFactory.getLogger(ManifestPluginDescriptorFinder.class);
+       
+       private PluginClasspath pluginClasspath;
+       
+       public ManifestPluginDescriptorFinder(PluginClasspath pluginClasspath) {
+               this.pluginClasspath = pluginClasspath;
+       }
+
+       @Override
+       public PluginDescriptor find(File pluginRepository) throws PluginException {
+       // TODO it's ok with first classes directory? Another idea is to specify in PluginClasspath the folder.
+               String classes = pluginClasspath.getClassesDirectories().get(0);
+        File manifestFile = new File(pluginRepository, classes + "/META-INF/MANIFEST.MF");
+        log.debug("Lookup plugin descriptor in '{}'", manifestFile);
+        if (!manifestFile.exists()) {
+            throw new PluginException("Cannot find '" + manifestFile + "' file");
+        }
+
+       FileInputStream input = null;
+               try {
+                       input = new FileInputStream(manifestFile);
+               } catch (FileNotFoundException e) {
+                       // not happening 
+               }
+               
+       Manifest manifest = null;
+        try {
+            manifest = new Manifest(input);
+        } catch (IOException e) {
+            throw new PluginException(e.getMessage(), e);
+        } finally {
+            try {
+                               input.close();
+                       } catch (IOException e) {
+                               throw new PluginException(e.getMessage(), e);
+                       }
+        } 
+        
+        PluginDescriptor pluginDescriptor = new PluginDescriptor();
+        
+        // TODO validate !!!
+        Attributes attrs = manifest.getMainAttributes();
+        String id = attrs.getValue("Plugin-Id");
+        if (StringUtils.isEmpty(id)) {
+               throw new PluginException("Plugin-Id cannot be empty");
+        }
+        pluginDescriptor.setPluginId(id);
+        
+        String clazz = attrs.getValue("Plugin-Class");
+        if (StringUtils.isEmpty(clazz)) {
+               throw new PluginException("Plugin-Class cannot be empty");
+        }
+        pluginDescriptor.setPluginClass(clazz);
+        
+        String version = attrs.getValue("Plugin-Version");
+        if (StringUtils.isEmpty(version)) {
+               throw new PluginException("Plugin-Version cannot be empty");
+        }
+        pluginDescriptor.setPluginVersion(PluginVersion.createVersion(version));
+        
+        String provider = attrs.getValue("Plugin-Provider");
+        pluginDescriptor.setProvider(provider);        
+        String dependencies = attrs.getValue("Plugin-Dependencies");
+        pluginDescriptor.setDependencies(dependencies);
+
+               return pluginDescriptor;
+       }
+       
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginClasspath.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginClasspath.java
new file mode 100644 (file)
index 0000000..23cd8f6
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 Decebal Suiu
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
+ * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The classpath of the plugin after it was unpacked. 
+ * It contains classes directories and lib directories (directories that contains jars). 
+ * All directories are relativ to plugin repository.
+ * The default values are "classes" and "lib". 
+ * 
+ * @author Decebal Suiu
+ */
+public class PluginClasspath {
+
+       private static final String DEFAULT_CLASSES_DIRECTORY = "classes";
+       private static final String DEFAULT_LIB_DIRECTORY = "lib";
+       
+       private List<String> classesDirectories;
+       private List<String> libDirectories;
+       
+       public PluginClasspath() {
+               classesDirectories = new ArrayList<String>();
+               libDirectories = new ArrayList<String>();
+               
+               // add defaults
+               classesDirectories.add(DEFAULT_CLASSES_DIRECTORY);
+               libDirectories.add(DEFAULT_LIB_DIRECTORY);
+       }
+
+       public List<String> getClassesDirectories() {
+               return classesDirectories;
+       }
+
+       public void setClassesDirectories(List<String> classesDirectories) {
+               this.classesDirectories = classesDirectories;
+       }
+
+       public List<String> getLibDirectories() {
+               return libDirectories;
+       }
+
+       public void setLibDirectories(List<String> libDirectories) {
+               this.libDirectories = libDirectories;
+       }
+       
+}
index d65b3f86735c610565b9107da2b8f8fb74cddabd..8bd2daa8630124f65439f946b1fabad7501d6c76 100644 (file)
@@ -15,6 +15,7 @@ package ro.fortsoft.pf4j;
 import java.io.File;
 import java.io.FileFilter;
 import java.net.MalformedURLException;
+import java.util.List;
 import java.util.Vector;
 
 import org.slf4j.Logger;
@@ -40,22 +41,12 @@ class PluginLoader {
      */
     private File pluginRepository;
 
-    /*
-     * The directory with '.class' files.
-     */
-    private File classesDirectory;
-
-    /*
-     * The directory with '.jar' files.
-     */
-    private File libDirectory;
-
+    private PluginClasspath pluginClasspath;
     private PluginClassLoader pluginClassLoader;
 
-    public PluginLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, File pluginRepository) {
+    public PluginLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, File pluginRepository, PluginClasspath pluginClasspath) {
         this.pluginRepository = pluginRepository;
-        classesDirectory = new File(pluginRepository, "classes");
-        libDirectory = new File(pluginRepository, "lib");
+        this.pluginClasspath = pluginClasspath; 
         ClassLoader parent = getClass().getClassLoader(); 
         pluginClassLoader = new PluginClassLoader(pluginManager, pluginDescriptor, parent);        
         log.debug("Created class loader {}", pluginClassLoader);
@@ -77,6 +68,60 @@ class PluginLoader {
        return loadClasses() && loadJars();
     }
 
+    private boolean loadClasses() {
+       List<String> classesDirectories = pluginClasspath.getClassesDirectories();
+       
+       // add each classes directory to plugin class loader
+       for (String classesDirectory : classesDirectories) {
+               // make 'classesDirectory' absolute
+               File file = new File(pluginRepository, classesDirectory).getAbsoluteFile();
+       
+               if (file.exists() && file.isDirectory()) {
+                   log.debug("Found '{}' directory", file.getPath());
+       
+                   try {
+                       pluginClassLoader.addURL(file.toURI().toURL());
+                       log.debug("Added '{}' to the class loader path", file);
+                   } catch (MalformedURLException e) {
+                       e.printStackTrace();
+                       log.error(e.getMessage(), e);
+                       return false;
+                   }
+               }
+       }
+
+        return true;
+    }
+
+    /**
+     * Add all *.jar files from lib directories to class loader.
+     */
+    private boolean loadJars() {
+       List<String> libDirectories = pluginClasspath.getLibDirectories();
+       
+       // add each jars directory to plugin class loader
+       for (String libDirectory : libDirectories) {
+               // make 'libDirectory' absolute
+               File file = new File(pluginRepository, libDirectory).getAbsoluteFile();
+       
+               // collect all jars from current lib directory in jars variable
+               Vector<File> jars = new Vector<File>();
+               getJars(jars, file);
+               for (File jar : jars) {
+                   try {
+                       pluginClassLoader.addURL(jar.toURI().toURL());
+                       log.debug("Added '{}' to the class loader path", jar);
+                   } catch (MalformedURLException e) {
+                       e.printStackTrace();
+                       log.error(e.getMessage(), e);
+                       return false;
+                   }
+               }
+       }
+
+        return true;
+    }
+
     private void getJars(Vector<File> bucket, File file) {
         FileFilter jarFilter = new JarFileFilter();
         FileFilter directoryFilter = new DirectoryFileFilter();
@@ -95,47 +140,4 @@ class PluginLoader {
         }
     }
 
-    private boolean loadClasses() {
-        // make 'classesDirectory' absolute
-        classesDirectory = classesDirectory.getAbsoluteFile();
-
-        if (classesDirectory.exists() && classesDirectory.isDirectory()) {
-            log.debug("Found '{}' directory", classesDirectory.getPath());
-
-            try {
-                pluginClassLoader.addURL(classesDirectory.toURI().toURL());
-                log.debug("Added '{}' to the class loader path", classesDirectory);
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-                log.error(e.getMessage(), e);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Add all *.jar files from '/lib' directory.
-     */
-    private boolean loadJars() {
-        // make 'jarDirectory' absolute
-        libDirectory = libDirectory.getAbsoluteFile();
-
-        Vector<File> jars = new Vector<File>();
-        getJars(jars, libDirectory);
-        for (File jar : jars) {
-            try {
-                pluginClassLoader.addURL(jar.toURI().toURL());
-                log.debug("Added '{}' to the class loader path", jar);
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-                log.error(e.getMessage(), e);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
 }
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java
new file mode 100644 (file)
index 0000000..3f5014c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Decebal Suiu
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
+ * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.java.sezpoz.Index;
+import net.java.sezpoz.IndexItem;
+
+/**
+ * Using Sezpoz(http://sezpoz.java.net/) for extensions discovery.
+ * 
+ * @author Decebal Suiu
+ */
+public class SezpozExtensionFinder implements ExtensionFinder {
+
+       private static final Logger log = LoggerFactory.getLogger(SezpozExtensionFinder.class);
+       
+       private volatile List<IndexItem<Extension, Object>> indices;
+       private ClassLoader classLoader;
+       
+       public SezpozExtensionFinder(ClassLoader classLoader) {
+               this.classLoader = classLoader;
+       }
+       
+       @Override
+       public <T> List<ExtensionWrapper<T>> find(Class<T> type) {
+               log.debug("Find extensions for {}", type);
+        List<ExtensionWrapper<T>> result = new ArrayList<ExtensionWrapper<T>>();
+               getIndices();
+//             System.out.println("indices =  "+ indices);
+               for (IndexItem<Extension, Object> item : indices) {
+            try {
+               AnnotatedElement element = item.element();
+               Class<?> extensionType = (Class<?>) element;
+               log.debug("Checking extension type {}", extensionType);
+               if (type.isAssignableFrom(extensionType)) {
+                    Object instance = item.instance();
+                    if (instance != null) {
+                               log.debug("Added extension {}", extensionType);
+                                               result.add(new ExtensionWrapper<T>(type.cast(instance), item.annotation().ordinal()));
+                    }
+                }
+            } catch (InstantiationException e) {
+               log.error(e.getMessage(), e);
+                       }
+               }
+               
+               return result;
+       }
+
+        private List<IndexItem<Extension, Object>> getIndices() {
+         if (indices == null) {
+             indices = new ArrayList<IndexItem<Extension, Object>>(); 
+             Iterator<IndexItem<Extension, Object>> it = Index.load(Extension.class, Object.class, classLoader).iterator();
+             while (it.hasNext()) {
+                indices.add(it.next());
+             }
+         }
+         
+         return indices;
+     }
+        
+}