View Javadoc
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 }