<commit_before>/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * 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 com.hazelcast.jet.impl.deployment;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.hazelcast.util.ExceptionUtil.rethrow;

public class JetClassLoader extends ClassLoader {
    private final List<ClassLoaderDelegate> loaders = new ArrayList<>();

    public JetClassLoader(ResourceStore resourceStore) {
        loaders.add(new SystemLoader());
        loaders.add(new ParentLoader());
        loaders.add(new CurrentLoader());
        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
            loaders.add(new UserClassLoader(resourceStore));
            return null;
        });

    }

    @Override
    public Class loadClass(String className) throws ClassNotFoundException {
        return loadClass(className, true);
    }

    @Override
    public Class loadClass(String className, boolean resolveIt) throws ClassNotFoundException {
        if (isEmpty(className)) {
            return null;
        }
        for (ClassLoaderDelegate loader : loaders) {
            final Class c = loader.loadClass(className, resolveIt);
            if (c != null) {
                return c;
            }
        }
        throw new ClassNotFoundException(className);
    }

    @Override
    public URL getResource(String name) {
        if (isEmpty(name)) {
            return null;
        }
        for (ClassLoaderDelegate loader : loaders) {
            URL url = loader.findResource(name);
            if (url != null) {
                return url;
            }
        }
        return null;
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        if (isEmpty(name)) {
            return null;
        }
        InputStream is = null;
        for (ClassLoaderDelegate loader : loaders) {
            is = loader.loadResource(name);
            if (is != null) {
                break;
            }
        }
        return is;
    }


    private static boolean isEmpty(String className) {
        return className == null || className.isEmpty();
    }

    private class SystemLoader implements ClassLoaderDelegate {
        @Override
        public Class loadClass(String className, boolean resolveIt) {
            try {
                return findSystemClass(className);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        @Override
        public InputStream loadResource(String name) {
            return getSystemResourceAsStream(name);
        }

        @Override
        public URL findResource(String name) {
            return getSystemResource(name);
        }
    }

    private class ParentLoader implements ClassLoaderDelegate {
        @Override
        public Class loadClass(String className, boolean resolveIt) {
            try {
                return getParent().loadClass(className);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        @Override
        public InputStream loadResource(String name) {
            return getParent().getResourceAsStream(name);
        }


        @Override
        public URL findResource(String name) {
            return getParent().getResource(name);
        }
    }

    private static class CurrentLoader implements ClassLoaderDelegate {
        @Override
        public Class loadClass(String className, boolean resolveIt) {
            try {
                return getClass().getClassLoader().loadClass(className);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        @Override
        public InputStream loadResource(String name) {
            return getClass().getClassLoader().getResourceAsStream(name);
        }


        @Override
        public URL findResource(String name) {
            return getClass().getClassLoader().getResource(name);
        }
    }

    private class UserClassLoader implements ClassLoaderDelegate {
        private final Map<String, Class> classes = new HashMap<>();

        private ResourceStore store;

        UserClassLoader(ResourceStore resourceStore) {
            this.store = resourceStore;
        }

        @Override
        public Class loadClass(String className, boolean resolveIt) {
            synchronized (getClassLoadingLock(className)) {
                final Class cached = classes.get(className);
                if (cached != null) {
                    return cached;
                }
                byte[] classBytes = classBytes(className);
                if (classBytes == null) {
                    return null;
                }
                final Class defined = defineClass(className, classBytes, 0, classBytes.length);
                if (defined == null) {
                    return null;
                }
                if (defined.getPackage() == null) {
                    int lastDotIndex = className.lastIndexOf('.');
                    String packageName = (lastDotIndex >= 0) ? className.substring(0, lastDotIndex) : "";
                    definePackage(packageName, null, null, null, null, null, null, null);
                }
                if (resolveIt) {
                    resolveClass(defined);
                }
                classes.put(className, defined);
                return defined;
            }
        }


        @Override
        public InputStream loadResource(String name) {
            byte[] arr = classBytes(name);
            if (arr == null) {
                ClassLoaderEntry classLoaderEntry = store.getDataEntries().get(name);<commit_msg>Fixed package definition bug around default package<commit_after>/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * 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 com.hazelcast.jet.impl.deployment;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.hazelcast.util.ExceptionUtil.rethrow;

public class JetClassLoader extends ClassLoader {
    private final List<ClassLoaderDelegate> loaders = new ArrayList<>();

    public JetClassLoader(ResourceStore resourceStore) {
        loaders.add(new SystemLoader());
        loaders.add(new ParentLoader());
        loaders.add(new CurrentLoader());
        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
            loaders.add(new UserClassLoader(resourceStore));
            return null;
        });

    }

    @Override
    public Class loadClass(String className) throws ClassNotFoundException {
        return loadClass(className, true);
    }

    @Override
    public Class loadClass(String className, boolean resolveIt) throws ClassNotFoundException {
        if (isEmpty(className)) {
            return null;
        }
        for (ClassLoaderDelegate loader : loaders) {
            final Class c = loader.loadClass(className, resolveIt);
            if (c != null) {
                return c;
            }
        }
        throw new ClassNotFoundException(className);
    }

    @Override
    public URL getResource(String name) {
        if (isEmpty(name)) {
            return null;
        }
        for (ClassLoaderDelegate loader : loaders) {
            URL url = loader.findResource(name);
            if (url != null) {
                return url;
            }
        }
        return null;
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        if (isEmpty(name)) {
            return null;
        }
        InputStream is = null;
        for (ClassLoaderDelegate loader : loaders) {
            is = loader.loadResource(name);
            if (is != null) {
                break;
            }
        }
        return is;
    }


    private static boolean isEmpty(String className) {
        return className == null || className.isEmpty();
    }

    private class SystemLoader implements ClassLoaderDelegate {
        @Override
        public Class loadClass(String className, boolean resolveIt) {
            try {
                return findSystemClass(className);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        @Override
        public InputStream loadResource(String name) {
            return getSystemResourceAsStream(name);
        }

        @Override
        public URL findResource(String name) {
            return getSystemResource(name);
        }
    }

    private class ParentLoader implements ClassLoaderDelegate {
        @Override
        public Class loadClass(String className, boolean resolveIt) {
            try {
                return getParent().loadClass(className);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        @Override
        public InputStream loadResource(String name) {
            return getParent().getResourceAsStream(name);
        }


        @Override
        public URL findResource(String name) {
            return getParent().getResource(name);
        }
    }

    private static class CurrentLoader implements ClassLoaderDelegate {
        @Override
        public Class loadClass(String className, boolean resolveIt) {
            try {
                return getClass().getClassLoader().loadClass(className);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        @Override
        public InputStream loadResource(String name) {
            return getClass().getClassLoader().getResourceAsStream(name);
        }


        @Override
        public URL findResource(String name) {
            return getClass().getClassLoader().getResource(name);
        }
    }

    private class UserClassLoader implements ClassLoaderDelegate {
        private final Map<String, Class> classes = new HashMap<>();

        private ResourceStore store;

        UserClassLoader(ResourceStore resourceStore) {
            this.store = resourceStore;
        }

        @Override
        public Class loadClass(String className, boolean resolveIt) {
            synchronized (getClassLoadingLock(className)) {
                final Class cached = classes.get(className);
                if (cached != null) {
                    return cached;
                }
                byte[] classBytes = classBytes(className);
                if (classBytes == null) {
                    return null;
                }
                final Class defined = defineClass(className, classBytes, 0, classBytes.length);
                if (defined == null) {
                    return null;
                }
                if (defined.getPackage() == null) {
                    int lastDotIndex = className.lastIndexOf('.');
                    if (lastDotIndex >= 0) {
                        String name = className.substring(0, lastDotIndex);
                        definePackage(name, null, null, null, null, null, null, null);
                    }
                }
                if (resolveIt) {
                    resolveClass(defined);
                }
                classes.put(className, defined);
                return defined;
            }
        }


        @Override
        public InputStream loadResource(String name) {
            byte[] arr = classBytes(name);
            if (arr == null) {
                ClassLoaderEntry classLoaderEntry = store.getDataEntries().get(name);
{'fraction_non_alphanumeric': 0.08215601965601965, 'fraction_numerical': 0.0023034398034398034, 'mean_word_length': 1.9223693067085483, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3637768', 'n_tokens_mistral': 3141, 'n_tokens_neox': 3022, 'n_words': 874}