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 }