~ubuntu-branches/ubuntu/precise/xom/precise

« back to all changes in this revision

Viewing changes to src/nu/xom/NodeFactory.java

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2007-11-25 15:50:40 UTC
  • Revision ID: james.westby@ubuntu.com-20071125155040-r75ikcqf1vu0cei7
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2002-2005 Elliotte Rusty Harold
 
2
   
 
3
   This library is free software; you can redistribute it and/or modify
 
4
   it under the terms of version 2.1 of the GNU Lesser General Public 
 
5
   License as published by the Free Software Foundation.
 
6
   
 
7
   This library is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 
10
   GNU Lesser General Public License for more details.
 
11
   
 
12
   You should have received a copy of the GNU Lesser General Public
 
13
   License along with this library; if not, write to the 
 
14
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 
15
   Boston, MA 02111-1307  USA
 
16
   
 
17
   You can contact Elliotte Rusty Harold by sending e-mail to
 
18
   elharo@metalab.unc.edu. Please include the word "XOM" in the
 
19
   subject line. The XOM home page is located at http://www.xom.nu/
 
20
*/
 
21
 
 
22
package nu.xom;
 
23
 
 
24
/**
 
25
 * <p>
 
26
 * Builders use a <code>NodeFactory</code> object
 
27
 * to construct each <code>Node</code> object (<code>Element</code>,
 
28
 * <code>Text</code>, <code>Attribute</code>, etc.) they add to the
 
29
 * tree. The default implementation simply calls the relevant 
 
30
 * constructor, stuffs the resulting <code>Node</code> object in a 
 
31
 * length one <code>Nodes</code> object, and returns it. 
 
32
 * </p>
 
33
 * 
 
34
 * <p>
 
35
 * Subclassing this class allows builders to produce
 
36
 * instance of subclasses (for example,
 
37
 * <code>HTMLElement</code>) instead of the
 
38
 * base classes.
 
39
 * </p>
 
40
 * 
 
41
 * <p>
 
42
 * Subclasses can also filter content while building.
 
43
 * For example, namespaces could be added to or changed 
 
44
 * on all elements. Comments could be deleted. Processing
 
45
 * instructions can be changed into elements. An 
 
46
 * <code>xinclude:include</code> element could be replaced
 
47
 * with the content it references. All such changes must be 
 
48
 * consistent with the usual rules of well-formedness. For 
 
49
 * example, the <code>makeDocType()</code> method should not 
 
50
 * return a list containing two <code>DocType</code> objects
 
51
 * because an XML document can have at most one document type
 
52
 * declaration. Nor should it return a list containing an element,
 
53
 * because an element cannot appear in a document prolog. However,
 
54
 * it could return a list containing any number of comments and
 
55
 * processing instructions, and not more than one <code>DocType</code> 
 
56
 * object.
 
57
 * </p>
 
58
 * 
 
59
 * @author Elliotte Rusty Harold
 
60
 * @version 1.1d5
 
61
 * 
 
62
 */
 
63
public class NodeFactory {
 
64
 
 
65
    /**
 
66
     * <p>
 
67
     * Constructs a new node factory.
 
68
     * </p>
 
69
     * 
 
70
     */
 
71
    public NodeFactory() {}
 
72
    
 
73
    /**
 
74
     * <p>
 
75
     * Creates a new element in the specified namespace 
 
76
     * with the specified name. The builder calls this
 
77
     * method to make the root element of the document.
 
78
     * </p>
 
79
     * 
 
80
     * <p>
 
81
     * Subclasses may change the name, namespace, content, or other 
 
82
     * characteristics of the element returned.
 
83
     * The default implementation merely calls 
 
84
     * <code>startMakingElement</code>. However, when subclassing, it 
 
85
     * is often useful to be able to easily distinguish between the  
 
86
     * root element and a non-root element because the root element   
 
87
     * cannot be detached. Therefore, subclasses must not return null  
 
88
     * from this method. Doing so will cause a 
 
89
     * <code>NullPointerException</code>.
 
90
     * </p>
 
91
     * 
 
92
     * @param name the qualified name of the element
 
93
     * @param namespace the namespace URI of the element
 
94
     * 
 
95
     * @return the new root element
 
96
     */
 
97
    public Element makeRootElement(String name, String namespace) {
 
98
        return startMakingElement(name, namespace);    
 
99
    }
 
100
 
 
101
    
 
102
    /**
 
103
     * <p>
 
104
     * Creates a new <code>Element</code> in the specified namespace 
 
105
     * with the specified name.
 
106
     * </p>
 
107
     * 
 
108
     * <p>
 
109
     * Subclasses may change the name, namespace, content, or other 
 
110
     * characteristics of the <code>Element</code> returned.
 
111
     * Subclasses may return null to indicate the 
 
112
     * <code>Element</code> should not be created.
 
113
     * However, doing so will only remove the element's start-tag and
 
114
     * end-tag from the result tree. Any content inside the element  
 
115
     * will be attached to the element's parent by default, unless it
 
116
     * too is filtered. To remove an entire element, return an empty
 
117
     * <code>Nodes</code> object from the 
 
118
     * <code>finishMakingElement()</code> method.
 
119
     * </p>
 
120
     * 
 
121
     * @param name the qualified name of the element
 
122
     * @param namespace the namespace URI of the element
 
123
     * 
 
124
     * @return the new element
 
125
     */
 
126
    public Element startMakingElement(String name, String namespace) {
 
127
        return new Element(name, namespace);    
 
128
    }
 
129
   
 
130
    
 
131
    /**
 
132
     * <p>
 
133
     * Signals the end of an element. This method should return 
 
134
     * the <code>Nodes</code> to be added to the tree.
 
135
     * They need not contain the <code>Element</code> that 
 
136
     * was passed to this method, though most often they will.
 
137
     * By default the <code>Nodes</code> returned contain
 
138
     * only the built element. However, subclasses may return
 
139
     * a list containing any number of nodes, all of which will be 
 
140
     * added to the tree at the current position in the order given by 
 
141
     * the list (subject to the usual well-formedness constraints, of 
 
142
     * course. For instance, the list should not contain a 
 
143
     * <code>DocType</code> object unless the element is the root 
 
144
     * element, and the document does not already have a 
 
145
     * <code>DocType</code>). All of the nodes returned must be 
 
146
     * parentless. If this method returns an empty list,
 
147
     * then the element (including all its contents) is not included 
 
148
     * in the finished document.
 
149
     * </p>
 
150
     * 
 
151
     * <p>
 
152
     * To process an element at a time, override this method in a 
 
153
     * subclass so that it functions as a callback. When you're done
 
154
     * processing the <code>Element</code>, return an empty list so  
 
155
     * that it will be removed from the tree and garbage collected.
 
156
     * Be careful not to return an empty list for the root element 
 
157
     * though. That is, when the element passed to this method is the 
 
158
     * root element, the list returned must contain exactly one 
 
159
     * <code>Element</code> object. The simplest way to check this 
 
160
     * is testing if <code>element.getParent() instanceof 
 
161
     * Document</code>.
 
162
     * </p>
 
163
     * 
 
164
     * <p>
 
165
     *  Do not detach <code>element</code> or any of its ancestors 
 
166
     *  while inside this method. Doing so can royally muck up the 
 
167
     *  build.
 
168
     * </p>
 
169
     * 
 
170
     * @param element the finished <code>Element</code>
 
171
     * 
 
172
     * @return the nodes to be added to the tree
 
173
     * 
 
174
     */
 
175
    public Nodes finishMakingElement(Element element) {
 
176
        return new Nodes(element);
 
177
    }
 
178
 
 
179
 
 
180
    /**
 
181
     * <p>
 
182
     * Creates a new <code>Document</code> object. 
 
183
     * The root element of this document is initially set to 
 
184
     * <code>&lt;root xmlns=http://www.xom.nu/fakeRoot""/></code>.
 
185
     * This is only temporary. As soon as the real root element's
 
186
     * start-tag is read, this element is replaced by the real root.
 
187
     * This fake root should never be exposed.
 
188
     * </p>
 
189
     * 
 
190
     * <p>
 
191
     *  The builder calls this method at the beginning of
 
192
     *  each document, before it calls any other method in this class.
 
193
     *  Thus this is a useful place to perform per-document 
 
194
     *  initialization tasks.
 
195
     * </p>
 
196
     * 
 
197
     * <p>
 
198
     *  Subclasses may change the root element, content, 
 
199
     *  or other characteristics of the document 
 
200
     *  returned. However, this method must not return null
 
201
     *  or the builder will throw a <code>ParsingException</code>.
 
202
     * </p>
 
203
     * 
 
204
     * @return the newly created <code>Document</code>
 
205
     */
 
206
    public Document startMakingDocument() {
 
207
        return new Document(
 
208
          Element.build("root", "http://www.xom.nu/fakeRoot", "root")
 
209
        );  
 
210
    }
 
211
    
 
212
    
 
213
    /**
 
214
     * <p>
 
215
     * Signals the end of a document. The default implementation of   
 
216
     * this method does nothing. The builder does not 
 
217
     * call this  method if an exception is thrown while building 
 
218
     * a document.
 
219
     * </p>
 
220
     * 
 
221
     * @param document the completed <code>Document</code>
 
222
     */
 
223
    public void finishMakingDocument(Document document) {}
 
224
 
 
225
    
 
226
    /**
 
227
     * <p>
 
228
     * Returns a new <code>Nodes</code> object containing an 
 
229
     * attribute in the specified namespace 
 
230
     * with the specified name and type.
 
231
     * </p>
 
232
     * 
 
233
     * <p>
 
234
     * Subclasses may change the nodes returned from this method.
 
235
     * They may return a <code>Nodes</code> object containing any 
 
236
     * number of children and attributes which are appended and 
 
237
     * added to the current parent element. This <code>Nodes</code> 
 
238
     * object may not contain any <code>Document</code> objects.
 
239
     * All of the nodes returned must be parentless.
 
240
     * Subclasses may return an empty <code>Nodes</code> to indicate  
 
241
     * the attribute should not be created.
 
242
     * </p>
 
243
     * 
 
244
     * @param name the prefixed name of the attribute
 
245
     * @param URI the namespace URI
 
246
     * @param value the attribute value
 
247
     * @param type the attribute type
 
248
     * 
 
249
     * @return the nodes to be added to the tree
 
250
     */
 
251
    public Nodes makeAttribute(String name, String URI, 
 
252
      String value, Attribute.Type type) {
 
253
        return new Nodes(new Attribute(name, URI, value, type));
 
254
    }
 
255
 
 
256
    
 
257
    /**
 
258
     * <p>
 
259
     * Returns a new <code>Nodes</code> object containing a 
 
260
     * comment with the specified text.
 
261
     * </p>
 
262
     * 
 
263
     * <p>
 
264
     * Subclasses may change the content or other 
 
265
     * characteristics of the comment returned. 
 
266
     * Subclasses may change the nodes returned from this method.
 
267
     * They may return a <code>Nodes</code> object containing any 
 
268
     * number of children and attributes which are appended and 
 
269
     * added to the current parent element. This <code>Nodes</code> 
 
270
     * object should not contain any <code>Document</code> objects.
 
271
     * All of the nodes returned must be parentless.
 
272
     * Subclasses may return an empty <code>Nodes</code> to indicate  
 
273
     * the comment should not be included in the 
 
274
     * finished document.
 
275
     * </p>
 
276
     * 
 
277
     * @param data the complete text content of the comment
 
278
     * 
 
279
     * @return the nodes to be added to the tree
 
280
     */
 
281
    public Nodes makeComment(String data) {
 
282
        return new Nodes(new Comment(data));   
 
283
    }
 
284
 
 
285
    
 
286
    /**
 
287
     * <p>
 
288
     * Returns a new <code>Nodes</code> object containing a 
 
289
     * <code>DocType</code> object with the specified root element
 
290
     * name, system ID, and public ID.
 
291
     * </p>
 
292
     * 
 
293
     * <p>
 
294
     * Subclasses may change the root element name, public ID, 
 
295
     * system ID, or other characteristics of the <code>DocType</code> 
 
296
     * returned. Subclasses may change the nodes returned from this 
 
297
     * method. They may return a <code>Nodes</code> object containing  
 
298
     * any number of comments and processing instructions which are  
 
299
     * appended to the current parent node. This <code>Nodes</code> 
 
300
     * object may not contain any <code>Document</code>,
 
301
     * <code>Element</code>, <code>Attribute</code>, or 
 
302
     * <code>Text</code> objects. All of the nodes returned must be 
 
303
     * parentless. Subclasses may return an empty <code>Nodes</code> to   
 
304
     * indicate the <code>DocType</code> should not be included in the 
 
305
     * finished document.
 
306
     * </p>
 
307
     *  
 
308
     * @param rootElementName the declared, qualified name 
 
309
     *   for the root element
 
310
     * @param publicID the public ID of the external DTD subset
 
311
     * @param systemID the URL of the external DTD subset
 
312
     * 
 
313
     * @return the nodes to be added to the document
 
314
     */
 
315
    public Nodes makeDocType(String rootElementName, 
 
316
      String publicID, String systemID) {
 
317
        return new Nodes(new DocType(rootElementName, publicID, systemID));    
 
318
    }
 
319
 
 
320
 
 
321
    /**
 
322
     * <p>
 
323
     * Returns a new <code>Nodes</code> object containing a 
 
324
     * text node with the specified content.
 
325
     * </p>
 
326
     * 
 
327
     * <p>
 
328
     * Subclasses may change the content or other characteristics of 
 
329
     * the text returned. Subclasses may also change the nodes 
 
330
     * returned from this method. They may return a <code>Nodes</code> 
 
331
     * object containing any number of nodes which are added or 
 
332
     * appended to the current parent node. This <code>Nodes</code> 
 
333
     * object must not contain any <code>Document</code> nodes. All of 
 
334
     * the nodes returned must be parentless. Subclasses may return an 
 
335
     * empty <code>Nodes</code> to indicate the text should not be 
 
336
     * included in the finished document.
 
337
     * </p> 
 
338
     * 
 
339
     * @param data the complete text content of the node
 
340
     * 
 
341
     * @return the nodes to be added to the tree
 
342
     */
 
343
    public Nodes makeText(String data) {
 
344
        return new Nodes(new Text(data));  
 
345
    }
 
346
 
 
347
    
 
348
    /**
 
349
     * <p>
 
350
     * Returns a new <code>Nodes</code> object containing a 
 
351
     * <code>CDATASection</code> node with the specified content.
 
352
     * </p>
 
353
     * 
 
354
     * @param data the complete text content of the node
 
355
     * 
 
356
     * @return the nodes to be added to the tree
 
357
     */
 
358
    Nodes makeCDATASection(String data) {
 
359
        return makeText(data);  
 
360
    } 
 
361
 
 
362
 
 
363
    /**
 
364
     * <p>
 
365
     * Returns a new <code>Nodes</code> object containing a 
 
366
     * new <code>ProcessingInstruction</code> object with
 
367
     * the specified target and data.
 
368
     * </p>
 
369
     * 
 
370
     * <p>
 
371
     * Subclasses may change the target, data, or other 
 
372
     * characteristics of the <code>ProcessingInstruction</code>
 
373
     * returned. Subclasses may change the nodes returned from this 
 
374
     * method. They may return a <code>Nodes</code> object containing 
 
375
     * any  number of nodes which are added or
 
376
     * appended to the current parent node. This <code>Nodes</code> 
 
377
     * object must not contain any <code>Document</code> nodes. 
 
378
     * If the processing instruction appears in the prolog or epilog
 
379
     * of the document, then it must also not contain any 
 
380
     * <code>Element</code>, <code>Attribute</code>, or 
 
381
     * <code>Text</code> objects.
 
382
     * All of the nodes returned must be parentless. Subclasses 
 
383
     * may return an empty <code>Nodes</code> to indicate the  
 
384
     * processing instruction should not be included in the 
 
385
     * finished document.
 
386
     * </p> 
 
387
     * 
 
388
     * @param target the target of the processing instruction
 
389
     * @param data the data of the processing instruction
 
390
     * 
 
391
     * @return the nodes to be added to the tree
 
392
     */
 
393
    public Nodes makeProcessingInstruction(
 
394
      String target, String data) {
 
395
        return new Nodes(new ProcessingInstruction(target, data)); 
 
396
    }
 
397
 
 
398
    
 
399
    void addAttribute(Element element, Attribute attribute) {
 
400
        element.addAttribute(attribute);
 
401
    }
 
402
  
 
403
    
 
404
    void insertChild(Element element, Node child, int position) {
 
405
        element.insertChild(child, position);
 
406
    }
 
407
  
 
408
    
 
409
}