805 806 /** 807 * Returns the set of the modules in this layer. 808 * 809 * @return A possibly-empty unmodifiable set of the modules in this layer 810 */ 811 public Set<Module> modules() { 812 Set<Module> modules = this.modules; 813 if (modules == null) { 814 this.modules = modules = 815 Collections.unmodifiableSet(new HashSet<>(nameToModule.values())); 816 } 817 return modules; 818 } 819 820 private volatile Set<Module> modules; 821 822 823 /** 824 * Returns the module with the given name in this layer, or if not in this 825 * layer, the {@linkplain #parents parent} layers. Finding a module in 826 * parent layers is equivalent to invoking {@code findModule} on each 827 * parent, in search order, until the module is found or all parents have 828 * been searched. In a <em>tree of layers</em> then this is equivalent to 829 * a depth-first search. 830 * 831 * @param name 832 * The name of the module to find 833 * 834 * @return The module with the given name or an empty {@code Optional} 835 * if there isn't a module with this name in this layer or any 836 * parent layer 837 */ 838 public Optional<Module> findModule(String name) { 839 Objects.requireNonNull(name); 840 if (this == EMPTY_LAYER) 841 return Optional.empty(); 842 Module m = nameToModule.get(name); 843 if (m != null) 844 return Optional.of(m); 845 846 return layers() 847 .skip(1) // skip this layer 848 .map(l -> l.nameToModule) 849 .filter(map -> map.containsKey(name)) 850 .map(map -> map.get(name)) 851 .findAny(); 852 } 853 854 855 /** 856 * Returns the {@code ClassLoader} for the module with the given name. If 857 * a module of the given name is not in this layer then the {@link #parents 858 * parent} layers are searched in the manner specified by {@link 859 * #findModule(String) findModule}. 860 * 861 * <p> If there is a security manager then its {@code checkPermission} 862 * method is called with a {@code RuntimePermission("getClassLoader")} 863 * permission to check that the caller is allowed to get access to the 864 * class loader. </p> 865 * 866 * @apiNote This method does not return an {@code Optional<ClassLoader>} 867 * because `null` must be used to represent the bootstrap class loader. 868 * 869 * @param name 870 * The name of the module to find 871 * 872 * @return The ClassLoader that the module is defined to 873 * 874 * @throws IllegalArgumentException if a module of the given name is not 875 * defined in this layer or any parent of this layer 876 * 877 * @throws SecurityException if denied by the security manager | 805 806 /** 807 * Returns the set of the modules in this layer. 808 * 809 * @return A possibly-empty unmodifiable set of the modules in this layer 810 */ 811 public Set<Module> modules() { 812 Set<Module> modules = this.modules; 813 if (modules == null) { 814 this.modules = modules = 815 Collections.unmodifiableSet(new HashSet<>(nameToModule.values())); 816 } 817 return modules; 818 } 819 820 private volatile Set<Module> modules; 821 822 823 /** 824 * Returns the module with the given name in this layer, or if not in this 825 * layer, the {@linkplain #parents() parent} layers. Finding a module in 826 * parent layers is equivalent to invoking {@code findModule} on each 827 * parent, in search order, until the module is found or all parents have 828 * been searched. In a <em>tree of layers</em> then this is equivalent to 829 * a depth-first search. 830 * 831 * @param name 832 * The name of the module to find 833 * 834 * @return The module with the given name or an empty {@code Optional} 835 * if there isn't a module with this name in this layer or any 836 * parent layer 837 */ 838 public Optional<Module> findModule(String name) { 839 Objects.requireNonNull(name); 840 if (this == EMPTY_LAYER) 841 return Optional.empty(); 842 Module m = nameToModule.get(name); 843 if (m != null) 844 return Optional.of(m); 845 846 return layers() 847 .skip(1) // skip this layer 848 .map(l -> l.nameToModule) 849 .filter(map -> map.containsKey(name)) 850 .map(map -> map.get(name)) 851 .findAny(); 852 } 853 854 855 /** 856 * Returns the {@code ClassLoader} for the module with the given name. If 857 * a module of the given name is not in this layer then the {@link #parents() 858 * parent} layers are searched in the manner specified by {@link 859 * #findModule(String) findModule}. 860 * 861 * <p> If there is a security manager then its {@code checkPermission} 862 * method is called with a {@code RuntimePermission("getClassLoader")} 863 * permission to check that the caller is allowed to get access to the 864 * class loader. </p> 865 * 866 * @apiNote This method does not return an {@code Optional<ClassLoader>} 867 * because `null` must be used to represent the bootstrap class loader. 868 * 869 * @param name 870 * The name of the module to find 871 * 872 * @return The ClassLoader that the module is defined to 873 * 874 * @throws IllegalArgumentException if a module of the given name is not 875 * defined in this layer or any parent of this layer 876 * 877 * @throws SecurityException if denied by the security manager |