<commit_before>/*
*    jETeL/Clover - Java based ETL application framework.
*    Copyright (C) 2005-06  <NAME> <<EMAIL>>
*    
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*    
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    
*    Lesser General Public License for more details.
*    
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*/
package org.jetel.plugin;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Plugin class loader is descendant of URLClassLoader and is used for particular plugins.
 * Added value is in loading classes from siblings plugins.
 * Fistly try loading class from system, then from ourselfs and finally from its siblings.
 * 
 * @author <NAME>
 *
 */
public class PluginClassLoader extends URLClassLoader {

    private PluginDescriptor pluginDescriptor;

    private PluginDescriptor[] importPlugins;
    
    /**
     * Constructor.
     * @param parent
     * @param pluginDescriptor
     */
    public PluginClassLoader(ClassLoader parent, PluginDescriptor pluginDescriptor) {
        super(pluginDescriptor.getLibraryURLs(), parent);
        
        this.pluginDescriptor = pluginDescriptor;
        collectImports();
    }

    /**
     * Collect all plugin descriptors, on which depends this plugin. 
     */
    private void collectImports() {
        PluginDescriptor pluginDescriptor;
        Collection prerequisites = getPluginDescriptor().getPrerequisites();
        List<PluginDescriptor> importPlugins = new ArrayList<PluginDescriptor>();
        
        for(Iterator it = prerequisites.iterator(); it.hasNext();) {
            PluginPrerequisite prerequisite = (PluginPrerequisite) it.next();
            pluginDescriptor = Plugins.getPluginDescriptor(prerequisite.getPluginId());
            if(pluginDescriptor != null) {
                importPlugins.add(pluginDescriptor);
            }
        }
        
        this.importPlugins = importPlugins.toArray(new PluginDescriptor[importPlugins.size()]);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            return super.findClass(name);
        } catch(ClassNotFoundException e) {
            return findClassInPrerequisities(name, null);
        }
    }
    
    synchronized public Class<?> findClass(String name, Set<String> seen) throws ClassNotFoundException {
        //firstly we will try if this class is not loaded yet
        Class<?> ret = null;
        ret = findLoadedClass(name);
        if(ret != null) {
            return ret; // found already loaded class in this plug-in
        }
        
        //secondly we try use findClass() method from URLClassLoader
        return findClass(name);
    }

   private Class<?> findClassInPrerequisities(String name, Set<String> seen) throws ClassNotFoundException {
       Class<?> ret = null;
       
       if(seen == null) {
           seen = new HashSet<String>();
       }
       seen.add(getPluginDescriptor().getId());

       //try all dependant plugins
       for(int i = 0; i < importPlugins.length; i++) {
           if(seen.contains(importPlugins[i].getId())) {
               continue;
           }
           try {
               return ((PluginClassLoader) importPlugins[i].getClassLoader()).findClass(name, seen);
           } catch(ClassNotFoundException e) {<commit_msg>findbugs fixed<commit_after>/*
*    jETeL/Clover - Java based ETL application framework.
*    Copyright (C) 2005-06  <NAME> <<EMAIL>>
*    
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*    
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    
*    Lesser General Public License for more details.
*    
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*/
package org.jetel.plugin;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Plugin class loader is descendant of URLClassLoader and is used for particular plugins.
 * Added value is in loading classes from siblings plugins.
 * Fistly try loading class from system, then from ourselfs and finally from its siblings.
 * 
 * @author <NAME>
 *
 */
public class PluginClassLoader extends URLClassLoader {

    private PluginDescriptor pluginDescriptor;

    private PluginDescriptor[] importPlugins;
    
    /**
     * Constructor.
     * @param parent
     * @param pluginDescriptor
     */
    public PluginClassLoader(ClassLoader parent, PluginDescriptor pluginDescriptor) {
        super(pluginDescriptor.getLibraryURLs(), parent);
        
        this.pluginDescriptor = pluginDescriptor;
        collectImports();
    }

    /**
     * Collect all plugin descriptors, on which depends this plugin. 
     */
    private void collectImports() {
        PluginDescriptor pluginDescriptor;
        Collection prerequisites = getPluginDescriptor().getPrerequisites();
        List<PluginDescriptor> importPlugins = new ArrayList<PluginDescriptor>();
        
        for(Iterator it = prerequisites.iterator(); it.hasNext();) {
            PluginPrerequisite prerequisite = (PluginPrerequisite) it.next();
            pluginDescriptor = Plugins.getPluginDescriptor(prerequisite.getPluginId());
            if(pluginDescriptor != null) {
                importPlugins.add(pluginDescriptor);
            }
        }
        
        this.importPlugins = importPlugins.toArray(new PluginDescriptor[importPlugins.size()]);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            return super.findClass(name);
        } catch(ClassNotFoundException e) {
            return findClassInPrerequisities(name, null);
        }
    }
    
    synchronized public Class<?> findClass(String name, Set<String> seen) throws ClassNotFoundException {
        //firstly we will try if this class is not loaded yet
        Class<?> ret = null;
        ret = findLoadedClass(name);
        if(ret != null) {
            return ret; // found already loaded class in this plug-in
        }
        
        //secondly we try use findClass() method from URLClassLoader
        return findClass(name);
    }

   private Class<?> findClassInPrerequisities(String name, Set<String> seen) throws ClassNotFoundException {
       if(seen == null) {
           seen = new HashSet<String>();
       }
       seen.add(getPluginDescriptor().getId());

       //try all dependant plugins
       for(int i = 0; i < importPlugins.length; i++) {
           if(seen.contains(importPlugins[i].getId())) {
               continue;
           }
           try {
               return ((PluginClassLoader) importPlugins[i].getClassLoader()).findClass(name, seen);
           } catch(ClassNotFoundException e) {
{'fraction_non_alphanumeric': 0.08687615526802218, 'fraction_numerical': 0.005668515095502156, 'mean_word_length': 2.745269958467928, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3017739', 'n_tokens_mistral': 2142, 'n_tokens_neox': 2069, 'n_words': 690}