23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package jdk.jpackage.internal; |
26 package jdk.jpackage.internal; |
27 |
27 |
28 import java.io.ByteArrayOutputStream; |
|
29 import java.io.File; |
28 import java.io.File; |
30 import java.io.FileInputStream; |
|
31 import java.io.BufferedInputStream; |
|
32 import java.io.IOException; |
29 import java.io.IOException; |
33 import java.io.InputStream; |
|
34 import java.nio.file.StandardCopyOption; |
|
35 import java.nio.file.Files; |
|
36 import java.text.MessageFormat; |
|
37 import java.util.Map; |
30 import java.util.Map; |
38 import java.util.ResourceBundle; |
|
39 |
31 |
40 import jdk.jpackage.internal.resources.ResourceLocator; |
|
41 |
32 |
42 /** |
33 /** |
43 * AbstractBundler |
34 * AbstractBundler |
44 * |
35 * |
45 * This is the base class all Bundlers extend from. |
36 * This is the base class all bundlers extend from. |
46 * It contains methods and parameters common to all Bundlers. |
37 * It contains methods and parameters common to all bundlers. |
47 * The concrete implementations are in the platform specific Bundlers. |
38 * The concrete implementations are in the platform specific bundlers. |
48 */ |
39 */ |
49 public abstract class AbstractBundler implements Bundler { |
40 abstract class AbstractBundler implements Bundler { |
50 |
|
51 private static final ResourceBundle I18N = ResourceBundle.getBundle( |
|
52 "jdk.jpackage.internal.resources.MainResources"); |
|
53 |
41 |
54 static final BundlerParamInfo<File> IMAGES_ROOT = |
42 static final BundlerParamInfo<File> IMAGES_ROOT = |
55 new StandardBundlerParam<>( |
43 new StandardBundlerParam<>( |
56 "imagesRoot", |
44 "imagesRoot", |
57 File.class, |
45 File.class, |
58 params -> new File( |
46 params -> new File( |
59 StandardBundlerParam.TEMP_ROOT.fetchFrom(params), "images"), |
47 StandardBundlerParam.TEMP_ROOT.fetchFrom(params), "images"), |
60 (s, p) -> null); |
48 (s, p) -> null); |
61 |
|
62 public InputStream getResourceAsStream(String name) { |
|
63 return ResourceLocator.class.getResourceAsStream(name); |
|
64 } |
|
65 |
|
66 protected void fetchResource(String publicName, String category, |
|
67 String defaultName, File result, boolean verbose, File publicRoot) |
|
68 throws IOException { |
|
69 |
|
70 try (InputStream is = streamResource(publicName, category, |
|
71 defaultName, verbose, publicRoot)) { |
|
72 if (is != null) { |
|
73 Files.copy(is, result.toPath(), |
|
74 StandardCopyOption.REPLACE_EXISTING); |
|
75 } else { |
|
76 if (verbose) { |
|
77 Log.verbose(MessageFormat.format(I18N.getString( |
|
78 "message.no-default-resource"), |
|
79 defaultName == null ? "" : defaultName, |
|
80 category == null ? "" : "[" + category + "] ", |
|
81 publicName)); |
|
82 } |
|
83 } |
|
84 } |
|
85 } |
|
86 |
|
87 protected void fetchResource(String publicName, String category, |
|
88 File defaultFile, File result, boolean verbose, File publicRoot) |
|
89 throws IOException { |
|
90 |
|
91 try (InputStream is = streamResource(publicName, category, |
|
92 null, verbose, publicRoot)) { |
|
93 if (is != null) { |
|
94 Files.copy(is, result.toPath()); |
|
95 } else { |
|
96 IOUtils.copyFile(defaultFile, result); |
|
97 if (verbose) { |
|
98 Log.verbose(MessageFormat.format(I18N.getString( |
|
99 "message.using-custom-resource-from-file"), |
|
100 category == null ? "" : "[" + category + "] ", |
|
101 defaultFile.getAbsoluteFile())); |
|
102 } |
|
103 } |
|
104 } |
|
105 } |
|
106 |
|
107 private InputStream streamResource(String publicName, String category, |
|
108 String defaultName, boolean verbose, File publicRoot) |
|
109 throws IOException { |
|
110 boolean custom = false; |
|
111 InputStream is = null; |
|
112 if (publicName != null) { |
|
113 if (publicRoot != null) { |
|
114 File publicResource = new File(publicRoot, publicName); |
|
115 if (publicResource.exists() && publicResource.isFile()) { |
|
116 is = new BufferedInputStream( |
|
117 new FileInputStream(publicResource)); |
|
118 } |
|
119 } else { |
|
120 is = getResourceAsStream(publicName); |
|
121 } |
|
122 custom = (is != null); |
|
123 } |
|
124 if (is == null && defaultName != null) { |
|
125 is = getResourceAsStream(defaultName); |
|
126 } |
|
127 if (verbose && is != null) { |
|
128 String msg = null; |
|
129 if (custom) { |
|
130 msg = MessageFormat.format(I18N.getString( |
|
131 "message.using-custom-resource"), |
|
132 category == null ? |
|
133 "" : "[" + category + "] ", publicName); |
|
134 } else { |
|
135 msg = MessageFormat.format(I18N.getString( |
|
136 "message.using-default-resource"), |
|
137 defaultName == null ? "" : defaultName, |
|
138 category == null ? "" : "[" + category + "] ", |
|
139 publicName); |
|
140 } |
|
141 Log.verbose(msg); |
|
142 } |
|
143 return is; |
|
144 } |
|
145 |
|
146 protected String preprocessTextResource(String publicName, String category, |
|
147 String defaultName, Map<String, String> pairs, |
|
148 boolean verbose, File publicRoot) throws IOException { |
|
149 InputStream inp = streamResource( |
|
150 publicName, category, defaultName, verbose, publicRoot); |
|
151 if (inp == null) { |
|
152 throw new RuntimeException( |
|
153 "Jar corrupt? No " + defaultName + " resource!"); |
|
154 } |
|
155 |
|
156 // read fully into memory |
|
157 ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|
158 byte[] buffer = new byte[1024]; |
|
159 int length; |
|
160 while ((length = inp.read(buffer)) != -1) { |
|
161 baos.write(buffer, 0, length); |
|
162 } |
|
163 |
|
164 // substitute |
|
165 String result = new String(baos.toByteArray()); |
|
166 for (Map.Entry<String, String> e : pairs.entrySet()) { |
|
167 if (e.getValue() != null) { |
|
168 result = result.replace(e.getKey(), e.getValue()); |
|
169 } |
|
170 } |
|
171 return result; |
|
172 } |
|
173 |
49 |
174 @Override |
50 @Override |
175 public String toString() { |
51 public String toString() { |
176 return getName(); |
52 return getName(); |
177 } |
53 } |