15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.tools.jlink.internal;
26
27 import java.io.BufferedOutputStream;
28 import java.io.DataOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.nio.ByteOrder;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.util.ArrayList;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Objects;
40 import java.util.Set;
41 import java.util.stream.Collectors;
42 import java.util.stream.Stream;
43
44 import jdk.tools.jlink.internal.Archive.Entry;
45 import jdk.tools.jlink.internal.Archive.Entry.EntryType;
46 import jdk.tools.jlink.internal.ResourcePoolManager.CompressedModuleData;
47 import jdk.tools.jlink.plugin.PluginException;
48 import jdk.tools.jlink.plugin.ResourcePool;
49 import jdk.tools.jlink.plugin.ResourcePoolEntry;
50
51 /**
52 * An image (native endian.)
53 * <pre>{@code
54 * {
60 * u4 location_attributes_size;
61 * u4 strings_size;
62 * u4 redirect[table_length];
63 * u4 offsets[table_length];
64 * u1 location_attributes[location_attributes_size];
65 * u1 strings[strings_size];
66 * u1 content[if !EOF];
67 * }
68 * }</pre>
69 */
70 public final class ImageFileCreator {
71 private final Map<String, List<Entry>> entriesForModule = new HashMap<>();
72 private final ImagePluginStack plugins;
73 private ImageFileCreator(ImagePluginStack plugins) {
74 this.plugins = Objects.requireNonNull(plugins);
75 }
76
77 public static ExecutableImage create(Set<Archive> archives,
78 ImagePluginStack plugins)
79 throws IOException {
80 return ImageFileCreator.create(archives, ByteOrder.nativeOrder(),
81 plugins);
82 }
83
84 public static ExecutableImage create(Set<Archive> archives,
85 ByteOrder byteOrder)
86 throws IOException {
87 return ImageFileCreator.create(archives, byteOrder,
88 new ImagePluginStack());
89 }
90
91 public static ExecutableImage create(Set<Archive> archives,
92 ByteOrder byteOrder,
93 ImagePluginStack plugins)
94 throws IOException
95 {
96 ImageFileCreator image = new ImageFileCreator(plugins);
97 try {
98 image.readAllEntries(archives);
99 // write to modular image
100 image.writeImage(archives, byteOrder);
101 } finally {
102 //Close all archives
103 for (Archive a : archives) {
104 a.close();
105 }
106 }
107
108 return plugins.getExecutableImage();
109 }
110
111 private void readAllEntries(Set<Archive> archives) {
112 archives.stream().forEach((archive) -> {
113 Map<Boolean, List<Entry>> es;
114 try (Stream<Entry> entries = archive.entries()) {
115 es = entries.collect(Collectors.partitioningBy(n -> n.type()
116 == EntryType.CLASS_OR_RESOURCE));
117 }
118 String mn = archive.moduleName();
119 List<Entry> all = new ArrayList<>();
120 all.addAll(es.get(false));
136 return entries.collect(Collectors.toList());
137 }
138 }));
139 ByteOrder order = ByteOrder.nativeOrder();
140 BasicImageWriter writer = new BasicImageWriter(order);
141 ResourcePoolManager pool = createPoolManager(archives, entriesForModule, order, writer);
142 try (OutputStream fos = Files.newOutputStream(jimageFile);
143 BufferedOutputStream bos = new BufferedOutputStream(fos);
144 DataOutputStream out = new DataOutputStream(bos)) {
145 generateJImage(pool, writer, pluginSupport, out);
146 }
147 } finally {
148 //Close all archives
149 for (Archive a : archives) {
150 a.close();
151 }
152 }
153 }
154
155 private void writeImage(Set<Archive> archives,
156 ByteOrder byteOrder)
157 throws IOException {
158 BasicImageWriter writer = new BasicImageWriter(byteOrder);
159 ResourcePoolManager allContent = createPoolManager(archives,
160 entriesForModule, byteOrder, writer);
161 ResourcePool result = generateJImage(allContent,
162 writer, plugins, plugins.getJImageFileOutputStream());
163
164 //Handle files.
165 try {
166 plugins.storeFiles(allContent.resourcePool(), result, writer);
167 } catch (Exception ex) {
168 if (JlinkTask.DEBUG) {
169 ex.printStackTrace();
170 }
171 throw new IOException(ex);
172 }
173 }
174
175 private static ResourcePool generateJImage(ResourcePoolManager allContent,
176 BasicImageWriter writer,
177 ImagePluginStack pluginSupport,
178 DataOutputStream out
179 ) throws IOException {
180 ResourcePool resultResources;
181 try {
182 resultResources = pluginSupport.visitResources(allContent);
183 } catch (PluginException pe) {
184 if (JlinkTask.DEBUG) {
185 pe.printStackTrace();
186 }
|
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.tools.jlink.internal;
26
27 import java.io.BufferedOutputStream;
28 import java.io.DataOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.nio.ByteOrder;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Objects;
41 import java.util.Set;
42 import java.util.stream.Collectors;
43 import java.util.stream.Stream;
44
45 import jdk.tools.jlink.internal.Archive.Entry;
46 import jdk.tools.jlink.internal.Archive.Entry.EntryType;
47 import jdk.tools.jlink.internal.ResourcePoolManager.CompressedModuleData;
48 import jdk.tools.jlink.plugin.PluginException;
49 import jdk.tools.jlink.plugin.ResourcePool;
50 import jdk.tools.jlink.plugin.ResourcePoolEntry;
51
52 /**
53 * An image (native endian.)
54 * <pre>{@code
55 * {
61 * u4 location_attributes_size;
62 * u4 strings_size;
63 * u4 redirect[table_length];
64 * u4 offsets[table_length];
65 * u1 location_attributes[location_attributes_size];
66 * u1 strings[strings_size];
67 * u1 content[if !EOF];
68 * }
69 * }</pre>
70 */
71 public final class ImageFileCreator {
72 private final Map<String, List<Entry>> entriesForModule = new HashMap<>();
73 private final ImagePluginStack plugins;
74 private ImageFileCreator(ImagePluginStack plugins) {
75 this.plugins = Objects.requireNonNull(plugins);
76 }
77
78 public static ExecutableImage create(Set<Archive> archives,
79 ImagePluginStack plugins)
80 throws IOException {
81 return ImageFileCreator.create(archives, Collections.emptySet(), ByteOrder.nativeOrder(),
82 plugins);
83 }
84
85 public static ExecutableImage create(Set<Archive> archives,
86 ByteOrder byteOrder)
87 throws IOException {
88 return ImageFileCreator.create(archives, Collections.emptySet(), byteOrder,
89 new ImagePluginStack());
90 }
91
92 public static ExecutableImage create(Set<Archive> archives,
93 Set<String> rootModules,
94 ByteOrder byteOrder,
95 ImagePluginStack plugins)
96 throws IOException
97 {
98 ImageFileCreator image = new ImageFileCreator(plugins);
99 try {
100 image.readAllEntries(archives);
101 // write to modular image
102 image.writeImage(archives, rootModules, byteOrder);
103 } finally {
104 //Close all archives
105 for (Archive a : archives) {
106 a.close();
107 }
108 }
109
110 return plugins.getExecutableImage();
111 }
112
113 private void readAllEntries(Set<Archive> archives) {
114 archives.stream().forEach((archive) -> {
115 Map<Boolean, List<Entry>> es;
116 try (Stream<Entry> entries = archive.entries()) {
117 es = entries.collect(Collectors.partitioningBy(n -> n.type()
118 == EntryType.CLASS_OR_RESOURCE));
119 }
120 String mn = archive.moduleName();
121 List<Entry> all = new ArrayList<>();
122 all.addAll(es.get(false));
138 return entries.collect(Collectors.toList());
139 }
140 }));
141 ByteOrder order = ByteOrder.nativeOrder();
142 BasicImageWriter writer = new BasicImageWriter(order);
143 ResourcePoolManager pool = createPoolManager(archives, entriesForModule, order, writer);
144 try (OutputStream fos = Files.newOutputStream(jimageFile);
145 BufferedOutputStream bos = new BufferedOutputStream(fos);
146 DataOutputStream out = new DataOutputStream(bos)) {
147 generateJImage(pool, writer, pluginSupport, out);
148 }
149 } finally {
150 //Close all archives
151 for (Archive a : archives) {
152 a.close();
153 }
154 }
155 }
156
157 private void writeImage(Set<Archive> archives,
158 Set<String> rootModules,
159 ByteOrder byteOrder)
160 throws IOException {
161 BasicImageWriter writer = new BasicImageWriter(byteOrder);
162 ResourcePoolManager allContent = createPoolManager(archives,
163 entriesForModule, byteOrder, writer);
164 ResourcePool result = generateJImage(allContent,
165 writer, plugins, plugins.getJImageFileOutputStream());
166
167 //Handle files.
168 try {
169 plugins.storeFiles(rootModules, allContent.resourcePool(), result, writer);
170 } catch (Exception ex) {
171 if (JlinkTask.DEBUG) {
172 ex.printStackTrace();
173 }
174 throw new IOException(ex);
175 }
176 }
177
178 private static ResourcePool generateJImage(ResourcePoolManager allContent,
179 BasicImageWriter writer,
180 ImagePluginStack pluginSupport,
181 DataOutputStream out
182 ) throws IOException {
183 ResourcePool resultResources;
184 try {
185 resultResources = pluginSupport.visitResources(allContent);
186 } catch (PluginException pe) {
187 if (JlinkTask.DEBUG) {
188 pe.printStackTrace();
189 }
|