-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy pathbuild.xml
More file actions
376 lines (357 loc) · 14 KB
/
Copy pathbuild.xml
File metadata and controls
376 lines (357 loc) · 14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
<?xml version="1.0"?>
<project name="project" default="package" basedir=".">
<target name="package">
<!--
Create a new ant task <jarxbuild> for building a jar that self-
extracts by including org/gjt/cuspy/JarX.class. <jarxbuild> takes
one attribute, destfile= (which should be absolute, consider
specifying ${basedir} at the front). To specify what goes IN the
jar, supply nested zipfileset elements; that class was chosen
because it already supports prefix=, fullpath=, and filemode=
attributes to control the stored path and permission info, as well
as all the scanning/inclusion/exclusion rules you could want. But by
itself, it isn't enough to tell JarX which files are binary or text,
or the encodings of the text files. That is conveyed by which alias
is used for each zipfileset. That is, you don't literally use
nested <zipfileset> elements, but instead <binary>, <ascii>, or
<utf8> elements, which all are zipfilesets behind the scenes and
have all the same attributes and elements. Any files supplied in
a <binary> element will be archived and unarchived unchanged.
Files supplied in an <ascii> or <utf8> element will be treated as
text and have their line endings converted to local conventions on
extraction; they won't be transcoded, but will be stored in and
extracted from the jar in the specified encoding (and verified to
be well-formed in it). That obviously isn't a fully-general way to
specify the text handling, but it gets the job done, and if you have
another case to handle, just add another zipfileset <element> with
another name, and edit the javascript below to know what to do
with it.
To emphasize, files given in an <ascii> or <utf8> element are
extracted in exactly that encoding on any target platform regardless
of the platform's default encoding. That's appropriate for an
extension .control file (which must be <ascii> because PostgreSQL
assumes it), and any extension .sql scripts we supply (which must
be <utf8> because the .control file says so). It's possible that
for some other text files we might include (general docs or
what not), it would be nicer to let them be extracted into the
platform's default encoding (achieved by specifying a fixed value
such as UTF-8 for _JarX_CharsetInArchive while entirely omitting
_JarX_CharsetWhenUnpacked). But at the moment no such files are
being included, so I haven't provided another element name to give
that behavior.
There has to be a <binary> element supplying JarX.class itself.
The <jarxbuild> task also accepts nested text, which will be treated
as a path-resolver script (the language is assumed to be
application/javascript; I'm lazy). It will be stuffed into the
manifest in a form that survives manifest line-wrapping, and JarX
will use it at extraction time to rewrite pathnames. In this case,
that script (see further below) will use pg_config or system
properties to determine the extraction paths.
-->
<scriptdef name='jarxbuild' language='javascript'>
<attribute name='destfile'/>
<element type='zipfileset' name='binary'/>
<element type='zipfileset' name='ascii'/>
<element type='zipfileset' name='utf8'/>
<classpath>
<pathelement path='${classpath}'/>
<pathelement location='target/classes'/> <!-- JarX is there -->
</classpath>
<![CDATA[
var manifest = new java.util.jar.Manifest();
var sections = manifest.getEntries();
var mainsect = manifest.getMainAttributes();
mainsect.putValue('Manifest-Version', '1.0');
mainsect.putValue('Created-By', project.getProperty('project.name') + ' ' +
project.getProperty('project.version'));
mainsect.putValue('Main-Class', 'org.postgresql.pljava.packaging.Node');
/* Declare default permissions for entries that don't have their own.
*/
mainsect.putValue('_JarX_Permissions', 'read=all,write=none,execute=none');
/* Declare a function pathxfrm(p) if needed to convert from this platform's
file separator to the / used in the jar (just an identity function
if they are the same). The overcomplicated look is mostly to avoid using
replace(), which is a method (with different behavior) on both Java and
JavaScript strings, and Rhino and Nashorn have different rules about which
one you get.
*/
var filesep = project.getProperty('file.separator');
if ( filesep == '/' ) {
function pathxfrm(p) {
return p;
}
} else {
var fseprx = java.util.regex.Pattern.quote(filesep);
function pathxfrm(p) {
return p.replaceAll(fseprx, '/');
}
}
/* Munge a name (obtained directly from a resource in a fileset) according to
the prefix or fullpath given for the fileset itself.
*/
function munge(rsrc, fileset) {
var fullpath = fileset.getFullpath(project);
var prefix = fileset.getPrefix(project);
var n = pathxfrm(rsrc.getName());
/*
* The fullpath or prefix parts do not need to be pathxfrm()d; they are
* defined here in build.xml with / as the separator already.
*/
if ( !(null === fullpath || '' == fullpath) )
n = fullpath;
else if ( !(null === prefix) )
n = prefix + n;
return n;
}
/* Given one fileset, compute a set of manifest per-entry attributes from the
specified charset (caller supplied according to the alias name that was used
for the fileset) and file mode specified on the fileset, if any, then enter
a manifest section with those attributes for every resource name in the
fileset. Caller supplies charset === null for a fileset to be treated as
binary.
*/
function mksections(charset, fileset) {
var atts = new java.util.jar.Attributes();
if ( !(null === charset) ) {
atts.putValue('Content-Type', 'text/plain');
atts.putValue('_JarX_CharsetInArchive', charset);
atts.putValue('_JarX_CharsetWhenUnpacked', charset);
}
if ( fileset.hasFileModeBeenSet() ) {
var m = fileset.getFileMode(project) - 32768; /* don't ask me why */
if ( 0444 == m )
atts.putValue('_JarX_Permissions',
'read=all,write=none,execute=none');
else if ( 0555 == m )
atts.putValue('_JarX_Permissions',
'read=all,write=none,execute=all');
else
self.fail('File mode '+m+' not covered in script.');
}
var it = fileset.iterator();
while ( it.hasNext() ) {
var rsrc = it.next();
sections.put(munge(rsrc, fileset), atts);
}
}
/* Given a fileset and JarOutputStream, for each resource look up the manifest
per-entry section earlier created, pass that to builder.classify() to set
how shovel() will handle the contents, then make the next jar entry and
shovel the resource contents in.
*/
function storeset(fileset, jos) {
var it = fileset.iterator();
while ( it.hasNext() ) {
var rsrc = it.next();
var n = munge(rsrc, fileset);
var atts = sections.get(n);
builder.classify(atts, true);
var je = new java.util.jar.JarEntry(n);
jos.putNextEntry(je);
var instream = rsrc.getInputStream();
print(n+' ');
builder.shovel(instream, jos);
jos.closeEntry();
}
}
/* If there is text nested in the <jarxbuild> element, it is input to the
extractor's path resolver. Anticipating the removal of Nashorn in Java 15,
it is no longer assumed to be javax.script source or munged into the special
format documented in JarX, but just made directly the value of the
_JarX_PathResolver attribute. Node.java ignores it, has hardcoded rules.
*/
var pathresolver = self.text.trim();
if ( !(null === pathresolver || '' == pathresolver) ) {
mainsect.putValue('_JarX_PathResolver', pathresolver);
}
/* For each element name that can be used to supply a zipfileset, get all the
zipfilesets supplied under that name and pass them to mksections with the
appropriate charset parameter according to the element name.
*/
var binary = elements.get("binary");
for ( i = 0; i < binary.size(); ++i ) {
var fset = binary.get(i);
mksections(null, fset);
}
var ascii = elements.get("ascii");
for ( i = 0; i < ascii.size(); ++i ) {
var fset = ascii.get(i);
mksections('US-ASCII', fset);
}
var utf = elements.get("utf8");
for ( i = 0; i < utf.size(); ++i ) {
var fset = utf.get(i);
mksections('UTF-8', fset);
}
/* Set up the output archive...
*/
var builder = new org.gjt.cuspy.JarX.Build();
builder.setDefaults(mainsect);
var destf = attributes.get('destfile');
var fos = new java.io.FileOutputStream(destf);
var jos = new java.util.jar.JarOutputStream(fos, manifest);
/* Go through the supplied filesets once again, passing them to storeset...
*/
for ( i = 0; i < binary.size(); ++i ) {
var fset = binary.get(i);
storeset(fset, jos);
}
for ( i = 0; i < ascii.size(); ++i ) {
var fset = ascii.get(i);
storeset(fset, jos);
}
for ( i = 0; i < utf.size(); ++i ) {
var fset = utf.get(i);
storeset(fset, jos);
}
/* And finalize the output.
*/
jos.close();
]]>
</scriptdef>
<!-- Now build the jar using the <jarxbuild> task just created. -->
<jarxbuild
destfile="${basedir}/target/pljava-${PGSQL_VER_CLASSIFIER}.jar">
<binary dir="target/classes" includes="**/Node.class"/>
<binary dir="target/classes" includes="**/JarX.class"/>
<binary prefix="pljava/pkglibdir/" filemode="555"
dir="../pljava-so/target/pljava-pgxs/"
includes="**/*pljava-so*"/>
<binary dir="../pljava/target" includes="pljava*.jar"
prefix="pljava/sharedir/pljava/"/>
<binary dir="../pljava-api/target" includes="pljava-api*.jar"
prefix="pljava/sharedir/pljava/"/>
<binary dir="../pljava-examples/target"
includes="pljava-examples*.jar"
prefix="pljava/sharedir/pljava/"/>
<ascii dir="target/classes" includes="pljava.control"
prefix="pljava/sharedir/extension/"/>
<utf8 dir="target/classes" includes="pljava.sql"
fullpath="pljava/sharedir/pljava/pljava--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--unpackaged--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--unpackaged--${project.version}.sql"
/>
<!-- For any past version that has been released from which a
simple update is possible, just repeat the next entry, with
the from-version changed.
-->
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.10--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.9--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.8--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.7--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.6--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.5--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.4--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.3--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.2--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.1--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.6.0--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.8--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.7--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.6--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.5--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.4--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.3--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.2--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.1--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.1-BETA3--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.1-BETA2--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.1-BETA1--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.0--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.0-BETA3--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.0-BETA2--${project.version}.sql"
/>
<utf8 dir="target/classes" includes="pljava--.sql"
fullpath=
"pljava/sharedir/pljava/pljava--1.5.0-BETA1--${project.version}.sql"
/>
<utf8 dir="target/classes" prefix="pljava/sharedir/pljava/"
includes="*.sql"
excludes="pljava.sql pljava--.sql pljava--unpackaged--.sql"/>
<!-- Java Default Policy Implementation and ... Syntax says UTF8 -->
<utf8 dir="target/classes" prefix="pljava/sysconfdir/"
includes="pljava.policy"/>
<!-- If editing the script below, expand tabs to spaces (at 4 columns, and only
for the lines of the script) before saving. Line-wrapped into the manifest,
it looks horrible with tabs.
-->
(no script here; see Node.java for the rules to resolve using pg_config)
</jarxbuild>
</target>
</project>