Java tutorial
/* * Copyright 2015 MovingBlocks * * 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.terasology.module; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.module.exceptions.InvalidModulePathException; import org.terasology.util.Varargs; import java.io.File; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.CodeSource; import java.util.Collection; import java.util.Set; /** * A module that exists on the classpath. This means that it is always loaded and available, so should not be loaded in a secondary class loader. * * @author Immortius */ public final class ClasspathModule extends BaseModule { private static final Logger logger = LoggerFactory.getLogger(ClasspathModule.class); private final ImmutableList<URL> classpaths; /** * @param metadata Module metadata describing this module * @param paths a collection of paths to the module locations - may be a mixture of file and directory paths */ private ClasspathModule(ModuleMetadata metadata, Collection<Path> paths) { super(paths, metadata); logger.debug("Creating ClasspathModule '{}' with paths '{}'", metadata.getId(), paths); ImmutableList.Builder<URL> builder = ImmutableList.builder(); for (Path path : paths) { try { builder.add(path.toUri().toURL()); } catch (MalformedURLException e) { throw new InvalidModulePathException("Path cannot be converted to URL: " + path, e); } } classpaths = builder.build(); } /** * Creates a classpath module from a set of code sources. * <p> * There is an option to include directories on the classpath. This should only be done for one classpath module - this is for use when running from source * in environments that keep resources and classes in separate locations (e.g. gradle by default). Any directory on the classpath (as opposed to jars) will be * included in this module * </p> * * @param metadata Metadata describing the module to create * @param includeDirectories Whether to include directories on the classpath. * @param primarySource The first source to include in this module * @param additionalSources Any additional sources to include * @return A new ClasspathModule * @throws URISyntaxException If a source location cannot be converted to a proper URI (typically because the path to the source includes an invalid character). */ public static ClasspathModule create(ModuleMetadata metadata, boolean includeDirectories, CodeSource primarySource, CodeSource... additionalSources) throws URISyntaxException { Set<Path> paths = Sets.newLinkedHashSet(); for (CodeSource source : Varargs.combineToSet(primarySource, additionalSources)) { paths.add(Paths.get(source.getLocation().toURI())); } if (includeDirectories) { addClasspathDirectories(paths); } return new ClasspathModule(metadata, paths); } /** * Creates a classpath module from a set of representative classes. The code source (e.g. Jar or directory) for each class is included in the Classpath module. * * @param metadata Metadata describing the module to create * @param primaryClass The first representative class to include in the module * @param additionalClasses Any additional representative classes to include. * @return A new ClasspathModule * @throws URISyntaxException If a source location cannot be converted to a proper URI (typically because the path to the source includes an invalid character). */ public static ClasspathModule create(ModuleMetadata metadata, Class<?> primaryClass, Class<?>... additionalClasses) throws URISyntaxException { return create(metadata, false, primaryClass, additionalClasses); } /** * Creates a classpath module from a set of representative classes. The code source (e.g. Jar or directory) for each class is included in the Classpath module. * <p> * There is an option to include directories on the classpath. This should only be done for one classpath module - this is for use when running from source * in environments that keep resources and classes in separate locations (e.g. gradle by default). Any directory on the classpath (as opposed to jars) will be * included in this module * </p> * * @param metadata Metadata describing the module to create * @param includeDirectories Should directories on the classpath be included in this module? * @param primaryClass The first representative class to include in the module * @param additionalClasses Any additional representative classes to include. * @return A new ClasspathModule * @throws URISyntaxException If a source location cannot be converted to a proper URI (typically because the path to the source includes an invalid character). */ public static ClasspathModule create(ModuleMetadata metadata, boolean includeDirectories, Class<?> primaryClass, Class<?>... additionalClasses) throws URISyntaxException { Set<Path> paths = Sets.newLinkedHashSet(); for (Class<?> type : Varargs.combineToSet(primaryClass, additionalClasses)) { paths.add(Paths.get(type.getProtectionDomain().getCodeSource().getLocation().toURI())); } if (includeDirectories) { addClasspathDirectories(paths); } return new ClasspathModule(metadata, paths); } private static void addClasspathDirectories(Set<Path> paths) { for (String classpath : System.getProperty("java.class.path").split(File.pathSeparator)) { Path path = Paths.get(classpath); if (Files.isDirectory(path)) { paths.add(path); } } } @Override public ImmutableList<URL> getClasspaths() { return classpaths; } @Override public boolean isOnClasspath() { return true; } @Override public boolean isCodeModule() { return true; } }