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

sirius.kernel.Classpath Maven / Gradle / Ivy

Go to download

Provides common core classes and the microkernel powering all Sirius applications

There is a newer version: 12.9.1
Show newest version
/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.kernel;

import com.google.common.base.Objects;
import sirius.kernel.commons.Strings;
import sirius.kernel.health.Log;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * Retrieves a filtered list of resources in the classpath.
 * 

* This is used by the {@link sirius.kernel.di.Injector} to discover and register all classes in the * component model. Additionally {@link sirius.kernel.nls.Babelfish} uses this to load all relevant .properties files. *

* The method used, is to provide a name of a resource which is placed in every component root (jar file etc.) which * then can be discovered using Class.getResources. *

* Once a file pattern is given, all files in the classpath are scanned, starting from the detected roots. */ public class Classpath { /** * Logger used to log problems when scanning the classpath */ protected static final Log LOG = Log.get("classpath"); private List componentRoots; private ClassLoader loader; private String componentName; private List customizations; /** * Creates a new Classpath, scanning for component roots with the given name * * @param loader the class loader used to load the components * @param componentName the file name to identify component roots * @param customizations the list of active customizations to filter visible resources */ public Classpath(ClassLoader loader, String componentName, List customizations) { this.loader = loader; this.componentName = componentName; this.customizations = customizations; } /** * Returns the class loader used to load the classpath * * @return the class loader used by the framework */ public ClassLoader getLoader() { return loader; } /** * Returns all detected component roots * * @return a list of URLs pointing to the component roots */ public List getComponentRoots() { if (componentRoots == null) { try { componentRoots = Collections.list(loader.getResources(componentName)); componentRoots.sort(Comparator.comparing(URL::toString)); } catch (IOException e) { LOG.SEVERE(e); } } return componentRoots; } /** * Scans the classpath for files which relative path match the given patter * * @param pattern the pattern for the relative path used to filter files * @return a stream of matching elements */ public Stream find(final Pattern pattern) { return getComponentRoots().stream().flatMap(this::scan).filter(path -> { if (customizations != null && path.startsWith("customizations")) { String config = Sirius.getCustomizationName(path); return customizations.contains(config); } return true; }).map(pattern::matcher).filter(Matcher::matches); } /* * Scans all files below the given root URL. This can handle file:// and jar:// URLs */ private Stream scan(URL url) { List result = new ArrayList<>(); if ("file".equals(url.getProtocol())) { try { File file = new File(url.toURI().getPath()); if (!file.isDirectory()) { file = file.getParentFile(); } addFiles(file, result, file); } catch (URISyntaxException e) { LOG.SEVERE(e); } } else if ("jar".equals(url.getProtocol())) { try { JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile(); Enumeration e = jar.entries(); while (e.hasMoreElements()) { JarEntry entry = e.nextElement(); result.add(entry.getName()); } } catch (IOException e) { LOG.SEVERE(e); } } return result.stream(); } /* * DFS searcher for file / directory based classpath elements */ private void addFiles(File file, List collector, File reference) { if (!file.exists() || !file.isDirectory()) { return; } for (File child : file.listFiles()) { if (child.isDirectory()) { addFiles(child, collector, reference); } else { String path = buildRelativePath(reference, child); collector.add(path); } } } private String buildRelativePath(File reference, File child) { List path = new ArrayList<>(); File iter = child; while (iter != null && !Objects.equal(iter, reference)) { path.add(0, iter.getName()); iter = iter.getParentFile(); } return Strings.join(path, "/"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy