Clover coverage report - dom4j - 1.6.1 Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00 FRAMES NO FRAMES |
file stats: | LOC: | 603 |  | Methods: | 29
| NCLOC: | 383 |  | Classes: | 2
Source file | Conditionals | Statements | Methods | TOTAL
SAXEventRecorder.java | 0% | 0% | 0% | 0% |

1 |  | /*
2 |  | * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3 |  | *
4 |  | * This software is open source.
5 |  | * See the bottom of this file for the licence.
6 |  | */
7 |  |
8 |  | package org.dom4j.io;
9 |  |
10 |  | import java.io.Externalizable;
11 |  | import java.io.IOException;
12 |  | import java.io.ObjectInput;
13 |  | import java.io.ObjectOutput;
14 |  | import java.util.ArrayList;
15 |  | import java.util.HashMap;
16 |  | import java.util.Iterator;
17 |  | import java.util.List;
18 |  | import java.util.Map;
19 |  |
20 |  | import org.dom4j.Namespace;
21 |  | import org.dom4j.QName;
22 |  | import org.xml.sax.Attributes;
23 |  | import org.xml.sax.ContentHandler;
24 |  | import org.xml.sax.DTDHandler;
25 |  | import org.xml.sax.SAXException;
26 |  | import org.xml.sax.ext.DeclHandler;
27 |  | import org.xml.sax.ext.LexicalHandler;
28 |  | import org.xml.sax.helpers.AttributesImpl;
29 |  | import org.xml.sax.helpers.DefaultHandler;
30 |  |
31 |  | /**
32 |  | * <p>
33 |  | * Records SAX events such that they may be "replayed" at a later time. Provides
34 |  | * an alternative serialization approach when externalizing a DOM4J document.
35 |  | * Rather than serializing a document as text and re-parsing, the sax events may
36 |  | * be serialized instead.
37 |  | * </p>
38 |  | * Example usage:
39 |  | *
40 |  | * <pre>
41 |  | *
42 |  | *
43 |  | *
44 |  | * SAXEventRecorder recorder = new SAXEventRecorder();
45 |  | * SAXWriter saxWriter = new SAXWriter(recorder, recorder);
46 |  | * saxWriter.write(document);
47 |  | * out.writeObject(recorder);
48 |  | * ...
49 |  | * SAXEventRecorder recorder = (SAXEventRecorder)in.readObject();
50 |  | * SAXContentHandler saxContentHandler = new SAXContentHandler();
51 |  | * recorder.replay(saxContentHandler);
52 |  | * Document document = saxContentHandler.getDocument();
53 |  | *
54 |  | *
55 |  | *
56 |  | * </pre>
57 |  | *
58 |  | * @author Todd Wolff (Bluestem Software)
59 |  | */
60 |  | public class SAXEventRecorder extends DefaultHandler implements LexicalHandler,
61 |  | DeclHandler, DTDHandler, Externalizable {
62 |  | public static final long serialVersionUID = 1;
63 |  |
64 |  | private static final byte STRING = 0;
65 |  |
66 |  | private static final byte OBJECT = 1;
67 |  |
68 |  | private static final byte NULL = 2;
69 |  |
70 |  | private List events = new ArrayList();
71 |  |
72 |  | private Map prefixMappings = new HashMap();
73 |  |
74 |  | private static final String XMLNS = "xmlns";
75 |  |
76 |  | private static final String EMPTY_STRING = "";
77 |  |
78 | 0 | public SAXEventRecorder() {
79 |  | }
80 |  |
81 | 0 | public void replay(ContentHandler handler) throws SAXException {
82 | 0 | SAXEvent saxEvent;
83 | 0 | Iterator itr = events.iterator();
84 |  |
85 | 0 | while (itr.hasNext()) {
86 | 0 | saxEvent = (SAXEvent) itr.next();
87 |  |
88 | 0 | switch (saxEvent.event) {
89 |  | // replay to ContentHandler
90 | 0 | case SAXEvent.PROCESSING_INSTRUCTION:
91 | 0 | handler.processingInstruction((String) saxEvent.getParm(0),
92 |  | (String) saxEvent.getParm(1));
93 |  |
94 | 0 | break;
95 |  |
96 | 0 | case SAXEvent.START_PREFIX_MAPPING:
97 | 0 | handler.startPrefixMapping((String) saxEvent.getParm(0),
98 |  | (String) saxEvent.getParm(1));
99 |  |
100 | 0 | break;
101 |  |
102 | 0 | case SAXEvent.END_PREFIX_MAPPING:
103 | 0 | handler.endPrefixMapping((String) saxEvent.getParm(0));
104 |  |
105 | 0 | break;
106 |  |
107 | 0 | case SAXEvent.START_DOCUMENT:
108 | 0 | handler.startDocument();
109 |  |
110 | 0 | break;
111 |  |
112 | 0 | case SAXEvent.END_DOCUMENT:
113 | 0 | handler.endDocument();
114 |  |
115 | 0 | break;
116 |  |
117 | 0 | case SAXEvent.START_ELEMENT:
118 |  |
119 | 0 | AttributesImpl attributes = new AttributesImpl();
120 | 0 | List attParmList = (List) saxEvent.getParm(3);
121 |  |
122 | 0 | if (attParmList != null) {
123 | 0 | Iterator attsItr = attParmList.iterator();
124 |  |
125 | 0 | while (attsItr.hasNext()) {
126 | 0 | String[] attParms = (String[]) attsItr.next();
127 | 0 | attributes.addAttribute(attParms[0], attParms[1],
128 |  | attParms[2], attParms[3], attParms[4]);
129 |  | }
130 |  | }
131 |  |
132 | 0 | handler.startElement((String) saxEvent.getParm(0),
133 |  | (String) saxEvent.getParm(1), (String) saxEvent
134 |  | .getParm(2), attributes);
135 |  |
136 | 0 | break;
137 |  |
138 | 0 | case SAXEvent.END_ELEMENT:
139 | 0 | handler.endElement((String) saxEvent.getParm(0),
140 |  | (String) saxEvent.getParm(1), (String) saxEvent
141 |  | .getParm(2));
142 |  |
143 | 0 | break;
144 |  |
145 | 0 | case SAXEvent.CHARACTERS:
146 |  |
147 | 0 | char[] chars = (char[]) saxEvent.getParm(0);
148 | 0 | int start = ((Integer) saxEvent.getParm(1)).intValue();
149 | 0 | int end = ((Integer) saxEvent.getParm(2)).intValue();
150 | 0 | handler.characters(chars, start, end);
151 |  |
152 | 0 | break;
153 |  |
154 |  | // replay to LexicalHandler
155 | 0 | case SAXEvent.START_DTD:
156 | 0 | ((LexicalHandler) handler).startDTD((String) saxEvent
157 |  | .getParm(0), (String) saxEvent.getParm(1),
158 |  | (String) saxEvent.getParm(2));
159 |  |
160 | 0 | break;
161 |  |
162 | 0 | case SAXEvent.END_DTD:
163 | 0 | ((LexicalHandler) handler).endDTD();
164 |  |
165 | 0 | break;
166 |  |
167 | 0 | case SAXEvent.START_ENTITY:
168 | 0 | ((LexicalHandler) handler).startEntity((String) saxEvent
169 |  | .getParm(0));
170 |  |
171 | 0 | break;
172 |  |
173 | 0 | case SAXEvent.END_ENTITY:
174 | 0 | ((LexicalHandler) handler).endEntity((String) saxEvent
175 |  | .getParm(0));
176 |  |
177 | 0 | break;
178 |  |
179 | 0 | case SAXEvent.START_CDATA:
180 | 0 | ((LexicalHandler) handler).startCDATA();
181 |  |
182 | 0 | break;
183 |  |
184 | 0 | case SAXEvent.END_CDATA:
185 | 0 | ((LexicalHandler) handler).endCDATA();
186 |  |
187 | 0 | break;
188 |  |
189 | 0 | case SAXEvent.COMMENT:
190 |  |
191 | 0 | char[] cchars = (char[]) saxEvent.getParm(0);
192 | 0 | int cstart = ((Integer) saxEvent.getParm(1)).intValue();
193 | 0 | int cend = ((Integer) saxEvent.getParm(2)).intValue();
194 | 0 | ((LexicalHandler) handler).comment(cchars, cstart, cend);
195 |  |
196 | 0 | break;
197 |  |
198 |  | // replay to DeclHandler
199 | 0 | case SAXEvent.ELEMENT_DECL:
200 | 0 | ((DeclHandler) handler).elementDecl((String) saxEvent
201 |  | .getParm(0), (String) saxEvent.getParm(1));
202 |  |
203 | 0 | break;
204 |  |
205 | 0 | case SAXEvent.ATTRIBUTE_DECL:
206 | 0 | ((DeclHandler) handler).attributeDecl((String) saxEvent
207 |  | .getParm(0), (String) saxEvent.getParm(1),
208 |  | (String) saxEvent.getParm(2), (String) saxEvent
209 |  | .getParm(3), (String) saxEvent.getParm(4));
210 |  |
211 | 0 | break;
212 |  |
213 | 0 | case SAXEvent.INTERNAL_ENTITY_DECL:
214 | 0 | ((DeclHandler) handler).internalEntityDecl(
215 |  | (String) saxEvent.getParm(0), (String) saxEvent
216 |  | .getParm(1));
217 |  |
218 | 0 | break;
219 |  |
220 | 0 | case SAXEvent.EXTERNAL_ENTITY_DECL:
221 | 0 | ((DeclHandler) handler).externalEntityDecl(
222 |  | (String) saxEvent.getParm(0), (String) saxEvent
223 |  | .getParm(1), (String) saxEvent.getParm(2));
224 |  |
225 | 0 | break;
226 |  |
227 | 0 | default:
228 | 0 | throw new SAXException("Unrecognized event: "
229 |  | + saxEvent.event);
230 |  | }
231 |  | }
232 |  | }
233 |  |
234 |  | // ContentHandler interface
235 |  | // -------------------------------------------------------------------------
236 | 0 | public void processingInstruction(String target, String data)
237 |  | throws SAXException {
238 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.PROCESSING_INSTRUCTION);
239 | 0 | saxEvent.addParm(target);
240 | 0 | saxEvent.addParm(data);
241 | 0 | events.add(saxEvent);
242 |  | }
243 |  |
244 | 0 | public void startPrefixMapping(String prefix, String uri)
245 |  | throws SAXException {
246 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.START_PREFIX_MAPPING);
247 | 0 | saxEvent.addParm(prefix);
248 | 0 | saxEvent.addParm(uri);
249 | 0 | events.add(saxEvent);
250 |  | }
251 |  |
252 | 0 | public void endPrefixMapping(String prefix) throws SAXException {
253 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.END_PREFIX_MAPPING);
254 | 0 | saxEvent.addParm(prefix);
255 | 0 | events.add(saxEvent);
256 |  | }
257 |  |
258 | 0 | public void startDocument() throws SAXException {
259 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.START_DOCUMENT);
260 | 0 | events.add(saxEvent);
261 |  | }
262 |  |
263 | 0 | public void endDocument() throws SAXException {
264 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.END_DOCUMENT);
265 | 0 | events.add(saxEvent);
266 |  | }
267 |  |
268 | 0 | public void startElement(String namespaceURI, String localName,
269 |  | String qualifiedName, Attributes attributes) throws SAXException {
270 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.START_ELEMENT);
271 | 0 | saxEvent.addParm(namespaceURI);
272 | 0 | saxEvent.addParm(localName);
273 | 0 | saxEvent.addParm(qualifiedName);
274 |  |
275 | 0 | QName qName = null;
276 | 0 | if (namespaceURI != null) {
277 | 0 | qName = new QName(localName, Namespace.get(namespaceURI));
278 |  | } else {
279 | 0 | qName = new QName(localName);
280 |  | }
281 |  |
282 | 0 | if ((attributes != null) && (attributes.getLength() > 0)) {
283 | 0 | List attParmList = new ArrayList(attributes.getLength());
284 | 0 | String[] attParms = null;
285 |  |
286 | 0 | for (int i = 0; i < attributes.getLength(); i++) {
287 |  |
288 | 0 | String attLocalName = attributes.getLocalName(i);
289 |  |
290 | 0 | if (attLocalName.startsWith(XMLNS)) {
291 |  |
292 |  | // if SAXWriter is writing a DOMDocument, namespace
293 |  | // decls are treated as attributes. record a start
294 |  | // prefix mapping event
295 | 0 | String prefix = null;
296 | 0 | if (attLocalName.length() > 5) {
297 | 0 | prefix = attLocalName.substring(6);
298 |  | } else {
299 | 0 | prefix = EMPTY_STRING;
300 |  | }
301 |  |
302 | 0 | SAXEvent prefixEvent = new SAXEvent(
303 |  | SAXEvent.START_PREFIX_MAPPING);
304 | 0 | prefixEvent.addParm(prefix);
305 | 0 | prefixEvent.addParm(attributes.getValue(i));
306 | 0 | events.add(prefixEvent);
307 |  |
308 |  | // 'register' the prefix so that we can generate
309 |  | // an end prefix mapping event within endElement
310 | 0 | List prefixes = (List) prefixMappings.get(qName);
311 | 0 | if (prefixes == null) {
312 | 0 | prefixes = new ArrayList();
313 | 0 | prefixMappings.put(qName, prefixes);
314 |  | }
315 | 0 | prefixes.add(prefix);
316 |  |
317 |  | } else {
318 |  |
319 | 0 | attParms = new String[5];
320 | 0 | attParms[0] = attributes.getURI(i);
321 | 0 | attParms[1] = attLocalName;
322 | 0 | attParms[2] = attributes.getQName(i);
323 | 0 | attParms[3] = attributes.getType(i);
324 | 0 | attParms[4] = attributes.getValue(i);
325 | 0 | attParmList.add(attParms);
326 |  |
327 |  | }
328 |  |
329 |  | }
330 |  |
331 | 0 | saxEvent.addParm(attParmList);
332 |  | }
333 |  |
334 | 0 | events.add(saxEvent);
335 |  | }
336 |  |
337 | 0 | public void endElement(String namespaceURI, String localName, String qName)
338 |  | throws SAXException {
339 |  |
340 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.END_ELEMENT);
341 | 0 | saxEvent.addParm(namespaceURI);
342 | 0 | saxEvent.addParm(localName);
343 | 0 | saxEvent.addParm(qName);
344 | 0 | events.add(saxEvent);
345 |  |
346 |  | // check to see if a we issued a start prefix mapping event
347 |  | // for DOMDocument namespace decls
348 |  |
349 | 0 | QName elementName = null;
350 | 0 | if (namespaceURI != null) {
351 | 0 | elementName = new QName(localName, Namespace.get(namespaceURI));
352 |  | } else {
353 | 0 | elementName = new QName(localName);
354 |  | }
355 |  |
356 | 0 | List prefixes = (List) prefixMappings.get(elementName);
357 | 0 | if (prefixes != null) {
358 | 0 | Iterator itr = prefixes.iterator();
359 | 0 | while (itr.hasNext()) {
360 | 0 | SAXEvent prefixEvent =
361 |  | new SAXEvent(SAXEvent.END_PREFIX_MAPPING);
362 | 0 | prefixEvent.addParm(itr.next());
363 | 0 | events.add(prefixEvent);
364 |  | }
365 |  | }
366 |  |
367 |  | }
368 |  |
369 | 0 | public void characters(char[] ch, int start, int end) throws SAXException {
370 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.CHARACTERS);
371 | 0 | saxEvent.addParm(ch);
372 | 0 | saxEvent.addParm(new Integer(start));
373 | 0 | saxEvent.addParm(new Integer(end));
374 | 0 | events.add(saxEvent);
375 |  | }
376 |  |
377 |  | // LexicalHandler interface
378 |  | // -------------------------------------------------------------------------
379 | 0 | public void startDTD(String name, String publicId, String systemId)
380 |  | throws SAXException {
381 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.START_DTD);
382 | 0 | saxEvent.addParm(name);
383 | 0 | saxEvent.addParm(publicId);
384 | 0 | saxEvent.addParm(systemId);
385 | 0 | events.add(saxEvent);
386 |  | }
387 |  |
388 | 0 | public void endDTD() throws SAXException {
389 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.END_DTD);
390 | 0 | events.add(saxEvent);
391 |  | }
392 |  |
393 | 0 | public void startEntity(String name) throws SAXException {
394 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.START_ENTITY);
395 | 0 | saxEvent.addParm(name);
396 | 0 | events.add(saxEvent);
397 |  | }
398 |  |
399 | 0 | public void endEntity(String name) throws SAXException {
400 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.END_ENTITY);
401 | 0 | saxEvent.addParm(name);
402 | 0 | events.add(saxEvent);
403 |  | }
404 |  |
405 | 0 | public void startCDATA() throws SAXException {
406 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.START_CDATA);
407 | 0 | events.add(saxEvent);
408 |  | }
409 |  |
410 | 0 | public void endCDATA() throws SAXException {
411 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.END_CDATA);
412 | 0 | events.add(saxEvent);
413 |  | }
414 |  |
415 | 0 | public void comment(char[] ch, int start, int end) throws SAXException {
416 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.COMMENT);
417 | 0 | saxEvent.addParm(ch);
418 | 0 | saxEvent.addParm(new Integer(start));
419 | 0 | saxEvent.addParm(new Integer(end));
420 | 0 | events.add(saxEvent);
421 |  | }
422 |  |
423 |  | // DeclHandler interface
424 |  | // -------------------------------------------------------------------------
425 | 0 | public void elementDecl(String name, String model) throws SAXException {
426 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.ELEMENT_DECL);
427 | 0 | saxEvent.addParm(name);
428 | 0 | saxEvent.addParm(model);
429 | 0 | events.add(saxEvent);
430 |  | }
431 |  |
432 | 0 | public void attributeDecl(String eName, String aName, String type,
433 |  | String valueDefault, String value) throws SAXException {
434 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.ATTRIBUTE_DECL);
435 | 0 | saxEvent.addParm(eName);
436 | 0 | saxEvent.addParm(aName);
437 | 0 | saxEvent.addParm(type);
438 | 0 | saxEvent.addParm(valueDefault);
439 | 0 | saxEvent.addParm(value);
440 | 0 | events.add(saxEvent);
441 |  | }
442 |  |
443 | 0 | public void internalEntityDecl(String name, String value)
444 |  | throws SAXException {
445 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.INTERNAL_ENTITY_DECL);
446 | 0 | saxEvent.addParm(name);
447 | 0 | saxEvent.addParm(value);
448 | 0 | events.add(saxEvent);
449 |  | }
450 |  |
451 | 0 | public void externalEntityDecl(String name, String publicId, String sysId)
452 |  | throws SAXException {
453 | 0 | SAXEvent saxEvent = new SAXEvent(SAXEvent.EXTERNAL_ENTITY_DECL);
454 | 0 | saxEvent.addParm(name);
455 | 0 | saxEvent.addParm(publicId);
456 | 0 | saxEvent.addParm(sysId);
457 | 0 | events.add(saxEvent);
458 |  | }
459 |  |
460 | 0 | public void writeExternal(ObjectOutput out) throws IOException {
461 | 0 | if (events == null) {
462 | 0 | out.writeByte(NULL);
463 |  | } else {
464 | 0 | out.writeByte(OBJECT);
465 | 0 | out.writeObject(events);
466 |  | }
467 |  | }
468 |  |
469 | 0 | public void readExternal(ObjectInput in) throws ClassNotFoundException,
470 |  | IOException {
471 | 0 | if (in.readByte() != NULL) {
472 | 0 | events = (List) in.readObject();
473 |  | }
474 |  | }
475 |  |
476 |  | // SAXEvent inner class
477 |  | // -------------------------------------------------------------------------
478 |  | static class SAXEvent implements Externalizable {
479 |  | public static final long serialVersionUID = 1;
480 |  |
481 |  | static final byte PROCESSING_INSTRUCTION = 1;
482 |  |
483 |  | static final byte START_PREFIX_MAPPING = 2;
484 |  |
485 |  | static final byte END_PREFIX_MAPPING = 3;
486 |  |
487 |  | static final byte START_DOCUMENT = 4;
488 |  |
489 |  | static final byte END_DOCUMENT = 5;
490 |  |
491 |  | static final byte START_ELEMENT = 6;
492 |  |
493 |  | static final byte END_ELEMENT = 7;
494 |  |
495 |  | static final byte CHARACTERS = 8;
496 |  |
497 |  | static final byte START_DTD = 9;
498 |  |
499 |  | static final byte END_DTD = 10;
500 |  |
501 |  | static final byte START_ENTITY = 11;
502 |  |
503 |  | static final byte END_ENTITY = 12;
504 |  |
505 |  | static final byte START_CDATA = 13;
506 |  |
507 |  | static final byte END_CDATA = 14;
508 |  |
509 |  | static final byte COMMENT = 15;
510 |  |
511 |  | static final byte ELEMENT_DECL = 16;
512 |  |
513 |  | static final byte ATTRIBUTE_DECL = 17;
514 |  |
515 |  | static final byte INTERNAL_ENTITY_DECL = 18;
516 |  |
517 |  | static final byte EXTERNAL_ENTITY_DECL = 19;
518 |  |
519 |  | protected byte event;
520 |  |
521 |  | protected List parms;
522 |  |
523 | 0 | public SAXEvent() {
524 |  | }
525 |  |
526 | 0 | SAXEvent(byte event) {
527 | 0 | this.event = event;
528 |  | }
529 |  |
530 | 0 | void addParm(Object parm) {
531 | 0 | if (parms == null) {
532 | 0 | parms = new ArrayList(3);
533 |  | }
534 |  |
535 | 0 | parms.add(parm);
536 |  | }
537 |  |
538 | 0 | Object getParm(int index) {
539 | 0 | if ((parms != null) && (index < parms.size())) {
540 | 0 | return parms.get(index);
541 |  | } else {
542 | 0 | return null;
543 |  | }
544 |  | }
545 |  |
546 | 0 | public void writeExternal(ObjectOutput out) throws IOException {
547 | 0 | out.writeByte(event);
548 |  |
549 | 0 | if (parms == null) {
550 | 0 | out.writeByte(NULL);
551 |  | } else {
552 | 0 | out.writeByte(OBJECT);
553 | 0 | out.writeObject(parms);
554 |  | }
555 |  | }
556 |  |
557 | 0 | public void readExternal(ObjectInput in) throws ClassNotFoundException,
558 |  | IOException {
559 | 0 | event = in.readByte();
560 |  |
561 | 0 | if (in.readByte() != NULL) {
562 | 0 | parms = (List) in.readObject();
563 |  | }
564 |  | }
565 |  | }
566 |  | }
567 |  |
568 |  | /*
569 |  | * Redistribution and use of this software and associated documentation
570 |  | * ("Software"), with or without modification, are permitted provided that the
571 |  | * following conditions are met:
572 |  | *
573 |  | * 1. Redistributions of source code must retain copyright statements and
574 |  | * notices. Redistributions must also contain a copy of this document.
575 |  | *
576 |  | * 2. Redistributions in binary form must reproduce the above copyright notice,
577 |  | * this list of conditions and the following disclaimer in the documentation
578 |  | * and/or other materials provided with the distribution.
579 |  | *
580 |  | * 3. The name "DOM4J" must not be used to endorse or promote products derived
581 |  | * from this Software without prior written permission of MetaStuff, Ltd. For
582 |  | * written permission, please contact dom4j-info@metastuff.com.
583 |  | *
584 |  | * 4. Products derived from this Software may not be called "DOM4J" nor may
585 |  | * "DOM4J" appear in their names without prior written permission of MetaStuff,
586 |  | * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
587 |  | *
588 |  | * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
589 |  | *
590 |  | * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
591 |  | * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
592 |  | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
593 |  | * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
594 |  | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
595 |  | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
596 |  | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
597 |  | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
598 |  | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
599 |  | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
600 |  | * POSSIBILITY OF SUCH DAMAGE.
601 |  | *
602 |  | * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
603 |  | */