1 /*- 2 * #%L 3 * io.earcam.instrumental.module.jpms 4 * %% 5 * Copyright (C) 2018 earcam 6 * %% 7 * SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT) 8 * 9 * You <b>must</b> choose to accept, in full - any individual or combination of 10 * the following licenses: 11 * <ul> 12 * <li><a href="https://opensource.org/licenses/BSD-3-Clause">BSD-3-Clause</a></li> 13 * <li><a href="https://www.eclipse.org/legal/epl-v10.html">EPL-1.0</a></li> 14 * <li><a href="https://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></li> 15 * <li><a href="https://opensource.org/licenses/MIT">MIT</a></li> 16 * </ul> 17 * #L% 18 */ 19 package io.earcam.instrumental.module.jpms; 20 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.io.Serializable; 24 import java.nio.file.Path; 25 import java.util.Map; 26 import java.util.Optional; 27 import java.util.Set; 28 import java.util.SortedSet; 29 import java.util.jar.JarInputStream; 30 31 import javax.annotation.Nonnull; 32 import javax.annotation.Nullable; 33 import javax.annotation.WillClose; 34 import javax.annotation.WillNotClose; 35 36 /** 37 * 38 */ 39 public interface ModuleInfo extends Serializable { 40 41 /** 42 * @return a new {@link ModuleInfoBuilder}. 43 */ 44 public static ModuleInfoBuilder moduleInfo() 45 { 46 return new DefaultModuleInfo(); 47 } 48 49 50 /** 51 * <p> 52 * Read a {@code module-info.class} 53 * </p> 54 * 55 * @param bytecode the binary for {@code module-info.class} 56 * @return a {@link io.earcam.instrumental.module.jpms.ModuleInfo} object. 57 */ 58 public static ModuleInfo read(byte[] bytecode) 59 { 60 return BytecodeReader.read(bytecode); 61 } 62 63 64 /** 65 * <p> 66 * Read a {@code module-info.class}. The InputStream will not be closed, allowing 67 * use coding inspecting {@link JarInputStream} entries. 68 * </p> 69 * 70 * @param bytecode the {@link InputStream}, which at current point contains {@code module-info.class} 71 * @return a {@link io.earcam.instrumental.module.jpms.ModuleInfo} object. 72 * 73 * @throws java.io.IOException if any. 74 */ 75 public static ModuleInfo read(@WillNotClose InputStream bytecode) throws IOException 76 { 77 return BytecodeReader.read(bytecode); 78 } 79 80 81 /** 82 * Extracts a {@code module-info} from a JAR (zip or directory-as-exploded-JAR) 83 * 84 * @param jar path to the JAR 85 * @return a {@link ModuleInfo} instance, possibly {@link SYNTHETIC}, 86 * or {@link Optional#empty()} if no module-info can be derived. 87 * @throws IOException 88 * 89 * @see {@link #read(byte[])} to just read a {@code module-info.class} file 90 */ 91 public static Optional<ModuleInfo> extract(Path jar) throws IOException 92 { 93 return ModuleInfoExtractor.extract(jar); 94 } 95 96 97 /** 98 * Extracts a {@code module-info} from a {@link JarInputStream}. 99 * 100 * @param jar the JAR input stream. 101 * @return a {@link ModuleInfo} instance, possibly {@link SYNTHETIC}, 102 * or {@link Optional#empty()} if no module-info can be derived. 103 * @throws IOException 104 */ 105 public static Optional<ModuleInfo> extract(@WillClose JarInputStream jar) throws IOException 106 { 107 return ModuleInfoExtractor.extract(jar); 108 } 109 110 111 /** 112 * @return the module's name. 113 */ 114 public abstract @Nonnull String name(); 115 116 117 /** 118 * @return the module's version. 119 */ 120 public abstract @Nullable String version(); 121 122 123 /** 124 * @return the module's access flags. 125 */ 126 public abstract int access(); 127 128 129 /** 130 * @return the module's modifiers. 131 */ 132 public default Set<ModuleModifier> modifiers() 133 { 134 return Access.modifiers(ModuleModifier.class, access()); 135 } 136 137 138 /** 139 * @return the module's packages. 140 */ 141 public abstract SortedSet<CharSequence> packages(); 142 143 144 /** 145 * @return the module's <b>uses</b>. 146 */ 147 public abstract SortedSet<String> uses(); 148 149 150 /** 151 * @return the module's <b>provides</b>. 152 */ 153 public abstract Map<String, String[]> provides(); 154 155 156 /** 157 * @return the module's main-class to launch. 158 */ 159 public abstract String mainClass(); 160 161 162 /** 163 * @return the module's <b>requires</b>. 164 */ 165 public abstract Set<Require> requires(); 166 167 168 /** 169 * @return the module's <b>exports</b>. 170 */ 171 public abstract Set<Export> exports(); 172 173 174 /** 175 * @return the module's <b>opens</b>. 176 */ 177 public abstract Set<Export> opens(); 178 179 180 /** 181 * @return convert this model to bytecode. 182 */ 183 public abstract byte[] toBytecode(); 184 185 186 /** 187 * @return a mutable version of this model. 188 */ 189 public abstract ModuleInfoBuilder deconstruct(); 190 }