1
|
|
|
2
|
|
|
3
|
|
|
4
|
|
|
5
|
|
|
6
|
|
|
7
|
|
|
8
|
|
|
9
|
|
|
10
|
|
|
11
|
|
|
12
|
|
|
13
|
|
|
14
|
|
|
15
|
|
package org.apache.hivemind.ant;
|
16
|
|
|
17
|
|
import java.io.BufferedInputStream;
|
18
|
|
import java.io.BufferedOutputStream;
|
19
|
|
import java.io.File;
|
20
|
|
import java.io.FileOutputStream;
|
21
|
|
import java.io.IOException;
|
22
|
|
import java.io.InputStream;
|
23
|
|
import java.io.OutputStream;
|
24
|
|
import java.net.URL;
|
25
|
|
import java.util.ArrayList;
|
26
|
|
import java.util.List;
|
27
|
|
|
28
|
|
import javax.xml.parsers.DocumentBuilder;
|
29
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
30
|
|
import javax.xml.parsers.ParserConfigurationException;
|
31
|
|
|
32
|
|
import org.apache.hivemind.Resource;
|
33
|
|
import org.apache.hivemind.impl.RegistryBuilder;
|
34
|
|
import org.apache.hivemind.sdl.SDLDocumentAdaptor;
|
35
|
|
import org.apache.hivemind.util.FileResource;
|
36
|
|
import org.apache.hivemind.util.URLResource;
|
37
|
|
import org.apache.tools.ant.BuildException;
|
38
|
|
import org.apache.tools.ant.Task;
|
39
|
|
import org.apache.tools.ant.types.Path;
|
40
|
|
import org.apache.xml.serialize.OutputFormat;
|
41
|
|
import org.apache.xml.serialize.XMLSerializer;
|
42
|
|
import org.w3c.dom.Document;
|
43
|
|
import org.w3c.dom.Element;
|
44
|
|
import org.w3c.dom.NamedNodeMap;
|
45
|
|
import org.w3c.dom.Node;
|
46
|
|
import org.xml.sax.InputSource;
|
47
|
|
import org.xml.sax.SAXException;
|
48
|
|
import org.xml.sax.SAXParseException;
|
49
|
|
|
50
|
|
|
51
|
|
|
52
|
|
|
53
|
|
|
54
|
|
|
55
|
|
|
56
|
|
|
57
|
|
|
58
|
|
|
59
|
|
|
60
|
|
|
61
|
|
|
62
|
|
|
63
|
|
|
64
|
|
|
65
|
|
|
66
|
|
|
67
|
|
|
68
|
|
|
69
|
|
|
70
|
|
public class ConstructRegistry extends Task
|
71
|
|
{
|
72
|
|
private int _uid = 1;
|
73
|
|
|
74
|
|
private File _output;
|
75
|
|
private Path _descriptorsPath;
|
76
|
|
|
77
|
|
|
78
|
|
|
79
|
|
|
80
|
|
|
81
|
|
private List _resourceQueue = new ArrayList();
|
82
|
|
|
83
|
8
|
public void execute() throws BuildException
|
84
|
|
{
|
85
|
8
|
if (_output == null)
|
86
|
1
|
throw new BuildException("You must specify an output file");
|
87
|
|
|
88
|
7
|
if (_descriptorsPath == null)
|
89
|
1
|
throw new BuildException("You must specify a set of module descriptors");
|
90
|
|
|
91
|
6
|
long outputStamp = _output.lastModified();
|
92
|
|
|
93
|
6
|
String[] paths = _descriptorsPath.list();
|
94
|
6
|
int count = paths.length;
|
95
|
|
|
96
|
6
|
boolean needsUpdate = false;
|
97
|
|
|
98
|
6
|
File[] descriptors = new File[count];
|
99
|
|
|
100
|
6
|
for (int i = 0; i < count; i++)
|
101
|
|
{
|
102
|
12
|
File f = new File(paths[i]);
|
103
|
|
|
104
|
12
|
if (f.isDirectory())
|
105
|
0
|
continue;
|
106
|
|
|
107
|
12
|
if (f.lastModified() > outputStamp)
|
108
|
10
|
needsUpdate = true;
|
109
|
|
|
110
|
12
|
descriptors[i] = f;
|
111
|
|
}
|
112
|
|
|
113
|
6
|
if (needsUpdate)
|
114
|
|
{
|
115
|
5
|
Document registry = constructRegistry(descriptors);
|
116
|
|
|
117
|
5
|
log("Writing registry to " + _output);
|
118
|
|
|
119
|
5
|
writeDocument(registry, _output);
|
120
|
|
}
|
121
|
|
|
122
|
|
}
|
123
|
|
|
124
|
5
|
private DocumentBuilder getBuilder() throws ParserConfigurationException
|
125
|
|
{
|
126
|
5
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
127
|
|
|
128
|
5
|
factory.setIgnoringComments(true);
|
129
|
|
|
130
|
5
|
return factory.newDocumentBuilder();
|
131
|
|
}
|
132
|
|
|
133
|
5
|
private Document constructRegistry(File[] moduleDescriptors) throws BuildException
|
134
|
|
{
|
135
|
5
|
try
|
136
|
|
{
|
137
|
5
|
DocumentBuilder builder = getBuilder();
|
138
|
|
|
139
|
5
|
Document result = builder.newDocument();
|
140
|
|
|
141
|
5
|
Element registry = result.createElement("registry");
|
142
|
|
|
143
|
5
|
result.appendChild(registry);
|
144
|
|
|
145
|
5
|
enqueue(moduleDescriptors);
|
146
|
|
|
147
|
5
|
while (!_resourceQueue.isEmpty())
|
148
|
|
{
|
149
|
9
|
Resource r = (Resource) _resourceQueue.remove(0);
|
150
|
|
|
151
|
9
|
processResource(r, builder, registry);
|
152
|
|
}
|
153
|
|
|
154
|
5
|
return result;
|
155
|
|
}
|
156
|
|
catch (Exception ex)
|
157
|
|
{
|
158
|
0
|
throw new BuildException(ex);
|
159
|
|
}
|
160
|
|
}
|
161
|
|
|
162
|
5
|
private void enqueue(File[] descriptors) throws IOException
|
163
|
|
{
|
164
|
5
|
for (int i = 0; i < descriptors.length; i++)
|
165
|
10
|
enqueue(descriptors[i]);
|
166
|
|
}
|
167
|
|
|
168
|
|
|
169
|
|
|
170
|
|
|
171
|
|
|
172
|
10
|
private void enqueue(File file) throws IOException
|
173
|
|
{
|
174
|
|
|
175
|
|
|
176
|
10
|
if (file == null)
|
177
|
0
|
return;
|
178
|
|
|
179
|
10
|
if (file.getName().endsWith(".jar"))
|
180
|
|
{
|
181
|
2
|
enqueueJar(file);
|
182
|
2
|
return;
|
183
|
|
}
|
184
|
|
|
185
|
8
|
String path = file.getPath().replace('\\', '/');
|
186
|
|
|
187
|
8
|
Resource r = new FileResource(path);
|
188
|
|
|
189
|
8
|
enqueue(r);
|
190
|
|
}
|
191
|
|
|
192
|
9
|
private void enqueue(Resource resource)
|
193
|
|
{
|
194
|
9
|
_resourceQueue.add(resource);
|
195
|
|
}
|
196
|
|
|
197
|
2
|
private void enqueueJar(File jarFile) throws IOException
|
198
|
|
{
|
199
|
2
|
URL jarRootURL = new URL("jar:" + jarFile.toURL() + "!/");
|
200
|
|
|
201
|
2
|
Resource jarResource = new URLResource(jarRootURL);
|
202
|
|
|
203
|
2
|
enqueueIfExists(jarResource, RegistryBuilder.HIVE_MODULE_SDL);
|
204
|
2
|
enqueueIfExists(jarResource, RegistryBuilder.HIVE_MODULE_XML);
|
205
|
|
}
|
206
|
|
|
207
|
4
|
private void enqueueIfExists(Resource jarResource, String path)
|
208
|
|
{
|
209
|
4
|
Resource r = jarResource.getRelativeResource(path);
|
210
|
|
|
211
|
4
|
if (r.getResourceURL() != null)
|
212
|
1
|
enqueue(r);
|
213
|
|
}
|
214
|
|
|
215
|
9
|
private void processResource(
|
216
|
|
Resource descriptor,
|
217
|
|
DocumentBuilder builder,
|
218
|
|
Element registryElement)
|
219
|
|
throws SAXException, IOException
|
220
|
|
{
|
221
|
9
|
log("Reading " + descriptor);
|
222
|
|
|
223
|
9
|
Document module = parse(builder, descriptor);
|
224
|
|
|
225
|
9
|
Element e = module.getDocumentElement();
|
226
|
|
|
227
|
9
|
prepareModuleForInclusion(descriptor, e);
|
228
|
|
|
229
|
9
|
Document d = (Document) registryElement.getParentNode();
|
230
|
|
|
231
|
9
|
Node eCopy = d.importNode(e, true);
|
232
|
|
|
233
|
9
|
registryElement.appendChild(eCopy);
|
234
|
|
|
235
|
|
}
|
236
|
|
|
237
|
9
|
private Document parse(DocumentBuilder builder, Resource descriptor)
|
238
|
|
throws SAXException, IOException
|
239
|
|
{
|
240
|
9
|
String path = descriptor.getPath();
|
241
|
|
|
242
|
9
|
if (path.endsWith(".sdl"))
|
243
|
7
|
return parseSDL(builder, descriptor);
|
244
|
|
|
245
|
2
|
return parseXML(builder, descriptor);
|
246
|
|
}
|
247
|
|
|
248
|
7
|
private Document parseSDL(DocumentBuilder builder, Resource descriptor)
|
249
|
|
throws SAXParseException, IOException
|
250
|
|
{
|
251
|
7
|
Document result = builder.newDocument();
|
252
|
7
|
SDLDocumentAdaptor parser = new SDLDocumentAdaptor(result);
|
253
|
|
|
254
|
7
|
parser.parse(descriptor);
|
255
|
|
|
256
|
7
|
return result;
|
257
|
|
}
|
258
|
|
|
259
|
2
|
private Document parseXML(DocumentBuilder builder, Resource descriptor)
|
260
|
|
throws SAXException, IOException
|
261
|
|
{
|
262
|
2
|
URL resourceURL = descriptor.getResourceURL();
|
263
|
|
|
264
|
2
|
InputStream rawStream = resourceURL.openStream();
|
265
|
2
|
InputStream stream = new BufferedInputStream(rawStream);
|
266
|
|
|
267
|
2
|
InputSource source = new InputSource(stream);
|
268
|
|
|
269
|
2
|
try
|
270
|
|
{
|
271
|
2
|
return builder.parse(source);
|
272
|
|
}
|
273
|
|
finally
|
274
|
|
{
|
275
|
2
|
stream.close();
|
276
|
|
}
|
277
|
|
}
|
278
|
|
|
279
|
5
|
private void writeDocument(Document document, File file) throws BuildException
|
280
|
|
{
|
281
|
5
|
try
|
282
|
|
{
|
283
|
5
|
OutputStream out = new FileOutputStream(file);
|
284
|
5
|
BufferedOutputStream buffered = new BufferedOutputStream(out);
|
285
|
|
|
286
|
5
|
writeDocument(document, buffered);
|
287
|
|
|
288
|
5
|
buffered.close();
|
289
|
|
}
|
290
|
|
catch (IOException ex)
|
291
|
|
{
|
292
|
0
|
throw new BuildException(
|
293
|
|
"Unable to write registry to " + file + ": " + ex.getMessage(),
|
294
|
|
ex);
|
295
|
|
}
|
296
|
|
}
|
297
|
|
|
298
|
9
|
private void prepareModuleForInclusion(Resource currentResource, Element module)
|
299
|
|
{
|
300
|
9
|
NamedNodeMap attributes = module.getAttributes();
|
301
|
|
|
302
|
9
|
String moduleId = attributes.getNamedItem("id").getNodeValue();
|
303
|
|
|
304
|
9
|
for (int i = attributes.getLength() - 1; i >= 0; i--)
|
305
|
|
{
|
306
|
18
|
Node attr = attributes.item(i);
|
307
|
|
|
308
|
18
|
String name = attr.getNodeName();
|
309
|
|
|
310
|
18
|
if (name.indexOf(':') > 0)
|
311
|
0
|
attributes.removeNamedItem(name);
|
312
|
|
}
|
313
|
|
|
314
|
9
|
module.setAttribute("uid", Integer.toString(_uid++));
|
315
|
|
|
316
|
9
|
Node node = module.getFirstChild();
|
317
|
|
|
318
|
9
|
while (node != null)
|
319
|
|
{
|
320
|
75
|
if (node instanceof Element)
|
321
|
|
{
|
322
|
71
|
Element e = (Element) node;
|
323
|
|
|
324
|
71
|
e.setAttribute("uid", Integer.toString(_uid++));
|
325
|
|
|
326
|
71
|
String name = e.getTagName();
|
327
|
|
|
328
|
71
|
if (name.equals("service-point")
|
329
|
|
|| name.equals("configuration-point")
|
330
|
|
|| name.equals("schema"))
|
331
|
60
|
qualify(moduleId, e, "id");
|
332
|
|
|
333
|
71
|
if (name.equals("configuration-point"))
|
334
|
15
|
qualify(moduleId, e, "schema-id");
|
335
|
|
|
336
|
71
|
if (name.equals("service-point"))
|
337
|
30
|
qualify(moduleId, e, "parameters-schema-id");
|
338
|
|
|
339
|
|
|
340
|
|
|
341
|
71
|
if (name.equals("contribution"))
|
342
|
7
|
qualify(moduleId, e, "configuration-id");
|
343
|
|
|
344
|
71
|
if (name.equals("implementation"))
|
345
|
0
|
qualify(moduleId, e, "service-id");
|
346
|
|
|
347
|
71
|
if (name.equals("service-point") || name.equals("implementation"))
|
348
|
30
|
qualifyServiceIds(moduleId, e);
|
349
|
|
|
350
|
71
|
if (name.equals("sub-module"))
|
351
|
0
|
enqueueSubmodule(currentResource, e);
|
352
|
|
|
353
|
|
}
|
354
|
|
|
355
|
75
|
node = node.getNextSibling();
|
356
|
|
}
|
357
|
|
}
|
358
|
|
|
359
|
130
|
private void qualify(String moduleId, Element element, String attributeName)
|
360
|
|
{
|
361
|
130
|
String id = element.getAttribute(attributeName);
|
362
|
|
|
363
|
130
|
if (id == null || id.trim().length() == 0)
|
364
|
26
|
return;
|
365
|
|
|
366
|
104
|
if (id.indexOf('.') < 0)
|
367
|
104
|
element.setAttribute(attributeName, moduleId + "." + id);
|
368
|
|
}
|
369
|
|
|
370
|
30
|
private void qualifyServiceIds(String moduleId, Element element)
|
371
|
|
{
|
372
|
30
|
Node node = element.getFirstChild();
|
373
|
|
|
374
|
30
|
while (node != null)
|
375
|
|
{
|
376
|
64
|
if (node instanceof Element)
|
377
|
|
{
|
378
|
59
|
Element e = (Element) node;
|
379
|
|
|
380
|
59
|
String name = e.getTagName();
|
381
|
|
|
382
|
59
|
if (name.equals("invoke-factory") || name.equals("interceptor"))
|
383
|
18
|
qualify(moduleId, e, "service-id");
|
384
|
|
|
385
|
|
}
|
386
|
|
|
387
|
64
|
node = node.getNextSibling();
|
388
|
|
}
|
389
|
|
}
|
390
|
|
|
391
|
0
|
private void enqueueSubmodule(Resource currentResource, Element e)
|
392
|
|
{
|
393
|
0
|
String descriptor = e.getAttribute("descriptor");
|
394
|
|
|
395
|
0
|
Resource sub = currentResource.getRelativeResource(descriptor);
|
396
|
|
|
397
|
0
|
enqueue(sub);
|
398
|
|
}
|
399
|
|
|
400
|
5
|
private void writeDocument(Document document, OutputStream out) throws IOException
|
401
|
|
{
|
402
|
5
|
XMLSerializer serializer = new XMLSerializer(out, new OutputFormat(document, null, true));
|
403
|
5
|
serializer.serialize(document);
|
404
|
|
}
|
405
|
|
|
406
|
5
|
public Path createDescriptors()
|
407
|
|
{
|
408
|
5
|
_descriptorsPath = new Path(project);
|
409
|
5
|
return _descriptorsPath;
|
410
|
|
}
|
411
|
|
|
412
|
1
|
public File getOutput()
|
413
|
|
{
|
414
|
1
|
return _output;
|
415
|
|
}
|
416
|
|
|
417
|
6
|
public void setOutput(File file)
|
418
|
|
{
|
419
|
6
|
_output = file;
|
420
|
|
}
|
421
|
|
|
422
|
|
}
|
423
|
|
|