40 import java.text.MessageFormat;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.ResourceBundle;
46 import java.util.Set;
47
48 import static jdk.jpackage.internal.StandardBundlerParam.*;
49
50 public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
51
52 private static final ResourceBundle I18N = ResourceBundle.getBundle(
53 "jdk.jpackage.internal.resources.LinuxResources");
54
55 private static final String LIBRARY_NAME = "libapplauncher.so";
56
57 private final Path root;
58 private final Path appDir;
59 private final Path appModsDir;
60 private final String relativeModsDir;
61 private final Path runtimeDir;
62 private final Path binDir;
63 private final Path mdir;
64
65 private final Map<String, ? super Object> params;
66
67 public static final BundlerParamInfo<File> ICON_PNG =
68 new StandardBundlerParam<>(
69 "icon.png",
70 File.class,
71 params -> {
72 File f = ICON.fetchFrom(params);
73 if (f != null && !f.getName().toLowerCase().endsWith(".png")) {
74 Log.error(MessageFormat.format(I18N.getString(
75 "message.icon-not-png"), f));
76 return null;
77 }
78 return f;
79 },
80 (s, p) -> new File(s));
81
82 public LinuxAppImageBuilder(Map<String, Object> config, Path imageOutDir)
83 throws IOException {
84 super(config,
85 imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime"));
86
87 Objects.requireNonNull(imageOutDir);
88
89 this.root = imageOutDir.resolve(APP_NAME.fetchFrom(config));
90 this.appDir = root.resolve("app");
91 this.appModsDir = appDir.resolve("mods");
92 this.relativeModsDir = "app/mods";
93 this.runtimeDir = root.resolve("runtime");
94 this.binDir = root.resolve("bin");
95 this.mdir = runtimeDir.resolve("lib");
96 this.params = new HashMap<>();
97 config.entrySet().stream().forEach(e -> params.put(
98 e.getKey().toString(), e.getValue()));
99 Files.createDirectories(appDir);
100 Files.createDirectories(runtimeDir);
101 }
102
103 public LinuxAppImageBuilder(String appName, Path imageOutDir)
104 throws IOException {
105 super(null, imageOutDir.resolve(appName));
106
107 Objects.requireNonNull(imageOutDir);
108
109 this.root = imageOutDir.resolve(appName);
110 this.appDir = null;
111 this.appModsDir = null;
112 this.relativeModsDir = null;
113 this.runtimeDir = null;
114 this.binDir = null;
115 this.mdir = null;
116 this.params = new HashMap<>();
117 }
118
119 private void writeEntry(InputStream in, Path dstFile) throws IOException {
120 Files.createDirectories(dstFile.getParent());
121 Files.copy(in, dstFile);
122 }
123
124 // it is static for the sake of sharing with "installer" bundlers
125 // that may skip calls to validate/bundle in this class!
126 public static File getRootDir(File outDir,
127 Map<String, ? super Object> params) {
128 return new File(outDir, APP_NAME.fetchFrom(params));
129 }
130
131 public static String getLauncherRelativePath(
132 Map<String, ? super Object> params) {
136 private static String getLauncherName(Map<String, ? super Object> params) {
137 return APP_NAME.fetchFrom(params);
138 }
139
140 public static String getLauncherCfgName(
141 Map<String, ? super Object> params) {
142 return "app" + File.separator + APP_NAME.fetchFrom(params) + ".cfg";
143 }
144
145 @Override
146 public Path getAppDir() {
147 return appDir;
148 }
149
150 @Override
151 public Path getAppModsDir() {
152 return appModsDir;
153 }
154
155 @Override
156 public String getRelativeModsDir() {
157 return relativeModsDir;
158 }
159
160 @Override
161 public void prepareApplicationFiles() throws IOException {
162 Map<String, ? super Object> originalParams = new HashMap<>(params);
163
164 try {
165 IOUtils.writableOutputDir(root);
166 IOUtils.writableOutputDir(binDir);
167 } catch (PackagerException pe) {
168 throw new RuntimeException(pe);
169 }
170
171 // create the primary launcher
172 createLauncherForEntryPoint(params);
173
174 // Copy library to the launcher folder
175 try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
176 writeEntry(is_lib, binDir.resolve(LIBRARY_NAME));
177 }
178
179 // create the additional launchers, if any
180 List<Map<String, ? super Object>> entryPoints
189
190 // Copy icon to Resources folder
191 copyIcon();
192 }
193
194 @Override
195 public void prepareJreFiles() throws IOException {}
196
197 private void createLauncherForEntryPoint(
198 Map<String, ? super Object> params) throws IOException {
199 // Copy executable to Linux folder
200 Path executableFile = binDir.resolve(getLauncherName(params));
201 try (InputStream is_launcher =
202 getResourceAsStream("jpackageapplauncher")) {
203 writeEntry(is_launcher, executableFile);
204 }
205
206 executableFile.toFile().setExecutable(true, false);
207 executableFile.toFile().setWritable(true, true);
208
209 writeCfgFile(params, root.resolve(getLauncherCfgName(params)).toFile(),
210 "$APPDIR/runtime");
211 }
212
213 private void copyIcon() throws IOException {
214 File icon = ICON_PNG.fetchFrom(params);
215 if (icon != null) {
216 File iconTarget = new File(binDir.toFile(),
217 APP_NAME.fetchFrom(params) + ".png");
218 IOUtils.copyFile(icon, iconTarget);
219 }
220 }
221
222 private void copyApplication() throws IOException {
223 for (RelativeFileSet appResources :
224 APP_RESOURCES_LIST.fetchFrom(params)) {
225 if (appResources == null) {
226 throw new RuntimeException("Null app resources?");
227 }
228 File srcdir = appResources.getBaseDirectory();
229 for (String fname : appResources.getIncludedFiles()) {
230 copyEntry(appDir, srcdir, fname);
|
40 import java.text.MessageFormat;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.ResourceBundle;
46 import java.util.Set;
47
48 import static jdk.jpackage.internal.StandardBundlerParam.*;
49
50 public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
51
52 private static final ResourceBundle I18N = ResourceBundle.getBundle(
53 "jdk.jpackage.internal.resources.LinuxResources");
54
55 private static final String LIBRARY_NAME = "libapplauncher.so";
56
57 private final Path root;
58 private final Path appDir;
59 private final Path appModsDir;
60 private final Path runtimeDir;
61 private final Path binDir;
62 private final Path mdir;
63
64 private final Map<String, ? super Object> params;
65
66 public static final BundlerParamInfo<File> ICON_PNG =
67 new StandardBundlerParam<>(
68 "icon.png",
69 File.class,
70 params -> {
71 File f = ICON.fetchFrom(params);
72 if (f != null && !f.getName().toLowerCase().endsWith(".png")) {
73 Log.error(MessageFormat.format(I18N.getString(
74 "message.icon-not-png"), f));
75 return null;
76 }
77 return f;
78 },
79 (s, p) -> new File(s));
80
81 public LinuxAppImageBuilder(Map<String, Object> config, Path imageOutDir)
82 throws IOException {
83 super(config,
84 imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime"));
85
86 Objects.requireNonNull(imageOutDir);
87
88 this.root = imageOutDir.resolve(APP_NAME.fetchFrom(config));
89 this.appDir = root.resolve("app");
90 this.appModsDir = appDir.resolve("mods");
91 this.runtimeDir = root.resolve("runtime");
92 this.binDir = root.resolve("bin");
93 this.mdir = runtimeDir.resolve("lib");
94 this.params = new HashMap<>();
95 config.entrySet().stream().forEach(e -> params.put(
96 e.getKey().toString(), e.getValue()));
97 Files.createDirectories(appDir);
98 Files.createDirectories(runtimeDir);
99 }
100
101 public LinuxAppImageBuilder(String appName, Path imageOutDir)
102 throws IOException {
103 super(null, imageOutDir.resolve(appName));
104
105 Objects.requireNonNull(imageOutDir);
106
107 this.root = imageOutDir.resolve(appName);
108 this.appDir = null;
109 this.appModsDir = null;
110 this.runtimeDir = null;
111 this.binDir = null;
112 this.mdir = null;
113 this.params = new HashMap<>();
114 }
115
116 private void writeEntry(InputStream in, Path dstFile) throws IOException {
117 Files.createDirectories(dstFile.getParent());
118 Files.copy(in, dstFile);
119 }
120
121 // it is static for the sake of sharing with "installer" bundlers
122 // that may skip calls to validate/bundle in this class!
123 public static File getRootDir(File outDir,
124 Map<String, ? super Object> params) {
125 return new File(outDir, APP_NAME.fetchFrom(params));
126 }
127
128 public static String getLauncherRelativePath(
129 Map<String, ? super Object> params) {
133 private static String getLauncherName(Map<String, ? super Object> params) {
134 return APP_NAME.fetchFrom(params);
135 }
136
137 public static String getLauncherCfgName(
138 Map<String, ? super Object> params) {
139 return "app" + File.separator + APP_NAME.fetchFrom(params) + ".cfg";
140 }
141
142 @Override
143 public Path getAppDir() {
144 return appDir;
145 }
146
147 @Override
148 public Path getAppModsDir() {
149 return appModsDir;
150 }
151
152 @Override
153 public void prepareApplicationFiles() throws IOException {
154 Map<String, ? super Object> originalParams = new HashMap<>(params);
155
156 try {
157 IOUtils.writableOutputDir(root);
158 IOUtils.writableOutputDir(binDir);
159 } catch (PackagerException pe) {
160 throw new RuntimeException(pe);
161 }
162
163 // create the primary launcher
164 createLauncherForEntryPoint(params);
165
166 // Copy library to the launcher folder
167 try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
168 writeEntry(is_lib, binDir.resolve(LIBRARY_NAME));
169 }
170
171 // create the additional launchers, if any
172 List<Map<String, ? super Object>> entryPoints
181
182 // Copy icon to Resources folder
183 copyIcon();
184 }
185
186 @Override
187 public void prepareJreFiles() throws IOException {}
188
189 private void createLauncherForEntryPoint(
190 Map<String, ? super Object> params) throws IOException {
191 // Copy executable to Linux folder
192 Path executableFile = binDir.resolve(getLauncherName(params));
193 try (InputStream is_launcher =
194 getResourceAsStream("jpackageapplauncher")) {
195 writeEntry(is_launcher, executableFile);
196 }
197
198 executableFile.toFile().setExecutable(true, false);
199 executableFile.toFile().setWritable(true, true);
200
201 writeCfgFile(params, root.resolve(getLauncherCfgName(params)).toFile());
202 }
203
204 private void copyIcon() throws IOException {
205 File icon = ICON_PNG.fetchFrom(params);
206 if (icon != null) {
207 File iconTarget = new File(binDir.toFile(),
208 APP_NAME.fetchFrom(params) + ".png");
209 IOUtils.copyFile(icon, iconTarget);
210 }
211 }
212
213 private void copyApplication() throws IOException {
214 for (RelativeFileSet appResources :
215 APP_RESOURCES_LIST.fetchFrom(params)) {
216 if (appResources == null) {
217 throw new RuntimeException("Null app resources?");
218 }
219 File srcdir = appResources.getBaseDirectory();
220 for (String fname : appResources.getIncludedFiles()) {
221 copyEntry(appDir, srcdir, fname);
|