All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.modules.Utils Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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.modules;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Predicate;

import static java.nio.file.FileVisitResult.CONTINUE;
import static java.nio.file.FileVisitResult.SKIP_SUBTREE;
import static java.security.AccessController.doPrivileged;

/**
 * @author David M. Lloyd
 * @author Richard Opalka
 */
final class Utils {

    static final String MODULE_VERSION = "Module-Version";
    static final String DEPENDENCIES = "Dependencies";
    static final String EXPORT = "export";
    static final String OPTIONAL = "optional";
    static final String SERVICES = "services";
    static final String MODULES_DIR = "modules";
    static final String MODULE_FILE = "module.xml";
    static final String[] NO_STRINGS = new String[0];

    private Utils() {
        // forbidden instantiation
    }

    static final ModuleLoader JDK_MODULE_LOADER = new ModuleLoader(JDKModuleFinder.getInstance());

    static final Set MODULES_PACKAGES = Set.of(
            "org.jboss.modules",
            "org.jboss.modules.filter",
            "org.jboss.modules.log",
            "org.jboss.modules.management",
            "org.jboss.modules.maven",
            "org.jboss.modules.ref",
            "org.jboss.modules.security",
            "org.jboss.modules.xml"
    );
    private static final Set MODULES_PATHS = Set.of(
            "org/jboss/modules",
            "org/jboss/modules/filter",
            "org/jboss/modules/log",
            "org/jboss/modules/management",
            "org/jboss/modules/maven",
            "org/jboss/modules/ref",
            "org/jboss/modules/security",
            "org/jboss/modules/xml"
    );

    private static final ClassLoader SYSTEM_CLASS_LOADER = doPrivileged((PrivilegedAction) ClassLoader::getSystemClassLoader);
    private static final ClassLoader OUR_CLASS_LOADER = Utils.class.getClassLoader();

    static Set getJDKPaths() {
        Set pathSet = new FastCopyHashSet<>(1024);
        processRuntimeImages(pathSet);
        // TODO: Remove this stuff once jboss-modules is itself a module
        final String javaClassPath = AccessController.doPrivileged(new PropertyReadAction("java.class.path"));
        JDKPaths.processClassPathItem(javaClassPath, new FastCopyHashSet<>(1024), pathSet);
        pathSet.addAll(MODULES_PATHS);
        return pathSet;
    }

    static LocalLoader getSystemLocalLoader() {
        return new LocalLoader() {
            public Class loadClassLocal(final String name, final boolean resolve) {
                try {
                    return Class.forName(name, resolve, getPlatformClassLoader());
                } catch (ClassNotFoundException ignored) {
                    try {
                        return Class.forName(name, resolve, OUR_CLASS_LOADER);
                    } catch (ClassNotFoundException e) {
                        return null;
                    }
                }
            }

            public Package loadPackageLocal(final String name) {
                final Package pkg = getPlatformClassLoader().getDefinedPackage(name);
                return pkg != null ? pkg : OUR_CLASS_LOADER.getDefinedPackage(name);
            }

            public List loadResourceLocal(final String name) {
                final Enumeration urls;
                try {
                    urls = getSystemResources(name);
                } catch (IOException e) {
                    return Collections.emptyList();
                }
                final List list = new ArrayList<>();
                while (urls.hasMoreElements()) {
                    final URL url = urls.nextElement();
                    URLConnection connection = null;
                    try {
                        connection = doPrivileged(new GetURLConnectionAction(url));
                    } catch (PrivilegedActionException e) {
                        try {
                            throw e.getException();
                        } catch (IOException e2) {
                            // omit from list
                        } catch (RuntimeException re) {
                            throw re;
                        } catch (Exception e2) {
                            throw new UndeclaredThrowableException(e2);
                        }
                    }
                    list.add(new URLConnectionResource(connection));
                }
                return list;
            }
        };
    }

    static ClassLoader getPlatformClassLoader() {
        return SYSTEM_CLASS_LOADER;
    }

    static URL getSystemResource(final String name) {
        final URL resource = getPlatformClassLoader().getResource(name);
        return resource != null ? resource : OUR_CLASS_LOADER != null ? OUR_CLASS_LOADER.getResource(name) : ClassLoader.getSystemResource(name);
    }

    static Enumeration getSystemResources(final String name) throws IOException {
        final Enumeration resources = getPlatformClassLoader().getResources(name);
        return resources != null && resources.hasMoreElements() ? resources : OUR_CLASS_LOADER.getResources(name);
    }

    static InputStream getSystemResourceAsStream(final String name) {
        final InputStream stream = getPlatformClassLoader().getResourceAsStream(name);
        return stream != null ? stream : OUR_CLASS_LOADER != null ? OUR_CLASS_LOADER.getResourceAsStream(name) : ClassLoader.getSystemResourceAsStream(name);
    }

    static Class getSystemClass(final ConcurrentClassLoader caller, final String className) throws ClassNotFoundException {
        try {
            return getPlatformClassLoader().loadClass(className);
        } catch (ClassNotFoundException ignored) {
            return OUR_CLASS_LOADER != null ? OUR_CLASS_LOADER.loadClass(className) : caller.findSystemClassInternal(className);
        }
    }

    static  Iterable findServices(final Class serviceType, final Predicate> filter, final ClassLoader classLoader) {
        final Iterator> delegate = ServiceLoader.load(serviceType, classLoader).stream().iterator();
        return new Iterable<>() {
            public Iterator iterator() {
                return new Iterator<>() {
                    T next = null;

                    public boolean hasNext() {
                        ServiceLoader.Provider next;
                        while (this.next == null) {
                            if (!delegate.hasNext()) return false;
                            next = delegate.next();
                            if (filter.test(next.type())) {
                                this.next = next.get();
                                return true;
                            }
                        }
                        return true;
                    }

                    public T next() {
                        if (!hasNext()) throw new NoSuchElementException();
                        T next = this.next;
                        this.next = null;
                        return next;
                    }
                };
            }
        };
    }

    // === nested util stuff, non-API ===

    private static void processRuntimeImages(final Set pathSet) {
        try {
            for (final Path root : FileSystems.getFileSystem(new URI("jrt:/")).getRootDirectories()) {
                Files.walkFileTree(root, new JrtFileVisitor(pathSet));
            }
        } catch (final URISyntaxException | IOException e) {
            throw new IllegalStateException("Unable to process java runtime images");
        }
    }

    private static class JrtFileVisitor implements FileVisitor {

        private static final String SLASH = "/";
        private static final String PACKAGES = "/packages";
        private final Set pathSet;

        private JrtFileVisitor(final Set pathSet) {
            this.pathSet = pathSet;
        }

        @Override
        public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) {
            final String d = dir.toString();
            return d.equals(SLASH) || d.startsWith(PACKAGES) ? CONTINUE : SKIP_SUBTREE;
        }

        @Override
        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) {
            if (file.getNameCount() >= 3 && file.getName(0).toString().equals("packages")) {
                pathSet.add(file.getName(1).toString().replace('.', '/'));
            }
            return CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(final Path file, final IOException exc) {
            return CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) {
            return CONTINUE;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy