001: /*
002: * (c) Copyright 2000, 2001, 2002, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * All rights reserved.
004: * [See end of file]
005: * $Id: MoreTests.java,v 1.46 2008/01/02 13:55:35 jeremy_carroll Exp $
006: */
007:
008: package com.hp.hpl.jena.rdf.arp.test;
009:
010: import java.io.FileInputStream;
011: import java.io.FileNotFoundException;
012: import java.io.FileReader;
013: import java.io.IOException;
014: import java.io.InputStream;
015: import java.io.InputStreamReader;
016: import java.io.InterruptedIOException;
017: import java.io.StringReader;
018: import java.nio.charset.Charset;
019:
020: import junit.framework.Test;
021: import junit.framework.TestCase;
022: import junit.framework.TestSuite;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.xml.sax.ErrorHandler;
027: import org.xml.sax.SAXException;
028: import org.xml.sax.SAXParseException;
029:
030: import com.hp.hpl.jena.ontology.OntDocumentManager;
031: import com.hp.hpl.jena.rdf.arp.ALiteral;
032: import com.hp.hpl.jena.rdf.arp.ARP;
033: import com.hp.hpl.jena.rdf.arp.ARPErrorNumbers;
034: import com.hp.hpl.jena.rdf.arp.AResource;
035: import com.hp.hpl.jena.rdf.arp.ParseException;
036: import com.hp.hpl.jena.rdf.arp.StatementHandler;
037: import com.hp.hpl.jena.rdf.model.Model;
038: import com.hp.hpl.jena.rdf.model.ModelFactory;
039: import com.hp.hpl.jena.rdf.model.RDFErrorHandler;
040: import com.hp.hpl.jena.rdf.model.RDFReader;
041: import com.hp.hpl.jena.vocabulary.RDF;
042:
043: /**
044: * @author jjc
045: *
046: */
047: public class MoreTests extends TestCase implements RDFErrorHandler,
048: ARPErrorNumbers {
049: static private Log logger = LogFactory.getLog(MoreTests.class);
050:
051: static public Test suite() {
052: TestSuite suite = new TestSuite("ARP Plus");
053:
054: suite.addTest(TestErrorMsg.suite());
055:
056: suite.addTest(TestPropEltErrorMsg.suite());
057: suite.addTest(TestScope.suite());
058: suite.addTest(ExceptionTests.suite());
059:
060: suite.addTest(new MoreDOM2RDFTest("testDOMwithARP"));
061:
062: suite.addTest(new MoreTests("testIcu"));
063: suite.addTest(new MoreTests("testLatin1"));
064: suite.addTest(new MoreTests("testIcu2"));
065: suite.addTest(new MoreTests("testEncodingMismatch1"));
066: suite.addTest(new MoreTests("testEncodingMismatch2"));
067: suite.addTest(new MoreTests("testEncodingMismatch3"));
068: suite.addTest(new MoreTests("testNullBaseParamOK"));
069: suite.addTest(new MoreTests("testNullBaseParamError"));
070: suite.addTest(new MoreTests("testEmptyBaseParamOK"));
071: suite.addTest(new MoreTests("testEmptyBaseParamError"));
072: suite.addTest(new MoreTests("testBadBaseParamOK"));
073: suite.addTest(new MoreTests("testBadBaseParamError"));
074: suite.addTest(new MoreTests("testRelativeBaseParamOK"));
075: suite.addTest(new MoreTests("testRelativeBaseParamError"));
076: suite.addTest(new MoreTests("testBaseTruncation"));
077: suite.addTest(new MoreTests("testWineDefaultNS"));
078: suite.addTest(new MoreTests("testInterrupt"));
079: suite.addTest(new MoreTests("testDanBriXMLBase"));
080: suite.addTest(new MoreTests("testToString"));
081:
082: //for (int i=0; i< 20; i++ ) {
083: //suite.addTest(new MoreTests("testTokenGarbage1"));
084: //suite.addTest(new MoreTests("testTokenGarbage2"));
085: // suite.addTest(new MoreTests("testTokenGarbage1"));
086: // suite.addTest(new MoreTests("testTokenGarbage2"));
087: // suite.addTest(new MoreTests("testTokenGarbage1"));
088: // suite.addTest(new MoreTests("testTokenGarbage2"));
089: //}
090: return suite;
091: }
092:
093: public MoreTests(String s) {
094: super (s);
095: }
096:
097: protected Model createMemModel() {
098: return ModelFactory.createDefaultModel();
099: }
100:
101: public void setUp() {
102: // ensure the ont doc manager is in a consistent state
103: OntDocumentManager.getInstance().reset(true);
104: }
105:
106: public void testWineDefaultNS() throws IOException {
107: testWineNS(createMemModel());
108: testWineNS(ModelFactory.createOntologyModel());
109: }
110:
111: private void testWineNS(Model m) throws FileNotFoundException,
112: IOException {
113: InputStream in = new FileInputStream(
114: "testing/arp/xmlns/wine.rdf");
115: m.read(in, "");
116: in.close();
117: assertEquals(
118: "http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#",
119: m.getNsPrefixURI(""));
120: }
121:
122: public void testLatin1() throws IOException {
123: Model m = createMemModel();
124: RDFReader rdr = m.getReader();
125: InputStream r = new FileInputStream(
126: "testing/arp/i18n/latin1.rdf");
127:
128: rdr.setErrorHandler(this );
129: expected = new int[] { WARN_NONCANONICAL_IANA_NAME };
130: rdr.read(m, r, "http://example.org/");
131: checkExpected();
132: }
133:
134: public void testARPMacRoman() throws IOException {
135: Model m = createMemModel();
136: RDFReader rdr = m.getReader();
137: InputStream r = new FileInputStream(
138: "testing/arp/i18n/macroman.rdf");
139:
140: rdr.setErrorHandler(this );
141: expected = new int[] { WARN_UNSUPPORTED_ENCODING,
142: WARN_NON_IANA_ENCODING };
143: expected[Charset.isSupported("MacRoman") ? 0 : 1] = 0;
144: // Only one of the warnings is expected, which depends on Java version
145:
146: rdr.read(m, r, "http://example.org/");
147: checkExpected();
148: }
149:
150: public void testARPMacArabic() throws IOException {
151: Model m = createMemModel();
152: RDFReader rdr = m.getReader();
153: InputStream r = new FileInputStream(
154: "testing/arp/i18n/arabic-macarabic.rdf");
155:
156: rdr.setErrorHandler(this );
157: expected = new int[] { WARN_UNSUPPORTED_ENCODING,
158: WARN_NON_IANA_ENCODING };
159: expected[Charset.isSupported("MacArabic") ? 0 : 1] = 0;
160: // Only one of the warnings is expected, which depends on Java version
161: rdr.read(m, r, "http://example.org/");
162: checkExpected();
163: }
164:
165: public void testEncodingMismatch1() throws IOException {
166: Model m = createMemModel();
167: RDFReader rdr = m.getReader();
168: FileReader r = new FileReader(
169: "testing/wg/rdfms-syntax-incomplete/test001.rdf");
170: if (r.getEncoding().startsWith("UTF")) {
171: System.err
172: .println("WARNING: Encoding mismatch tests not executed on platform with default UTF encoding.");
173: return;
174: }
175: rdr.setErrorHandler(this );
176: expected = new int[] { WARN_ENCODING_MISMATCH };
177: rdr.read(m, r, "http://example.org/");
178: //System.err.println(m.size() + " triples read.");
179: checkExpected();
180:
181: }
182:
183: public void testIcu() throws IOException {
184: // "\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe"
185: // Normalizer. isNormalized(
186: // "\u0bcd\u0ba4\u0bbf\u0baf\u0bbe"
187: // ,Normalizer.NFC,0);
188:
189: Model m = createMemModel();
190: RDFReader rdr = m.getReader();
191: FileInputStream r = new FileInputStream(
192: "testing/arp/i18n/icubug.rdf");
193: rdr.setErrorHandler(this );
194: expected = new int[] { WARN_STRING_COMPOSING_CHAR };
195: rdr.read(m, r, "http://example.org/");
196: r.close();
197: checkExpected();
198:
199: }
200:
201: public void testIcu2() throws IOException {
202: // "\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe"
203: // Normalizer. isNormalized(
204: // "\u0bcd\u0ba4\u0bbf\u0baf\u0bbe"
205: // ,Normalizer.NFC,0);
206:
207: Model m = createMemModel();
208: RDFReader rdr = m.getReader();
209: FileInputStream r = new FileInputStream(
210: "testing/arp/i18n/icubugtwo.rdf");
211: rdr.setErrorHandler(this );
212: expected = new int[] { WARN_STRING_NOT_NORMAL_FORM_C };
213: rdr.read(m, r, "http://example.org/");
214: r.close();
215: checkExpected();
216:
217: }
218:
219: static class ToStringStatementHandler implements StatementHandler {
220: String obj;
221:
222: String subj;
223:
224: public void statement(AResource sub, AResource pred,
225: ALiteral lit) {
226: // System.out.println("(" + sub + ", " + pred + ", " + lit + ")");
227: subj = sub.toString();
228: }
229:
230: public void statement(AResource sub, AResource pred,
231: AResource ob) {
232: // System.out.println("(" + sub + ", " + pred + ", " + ob + ")");
233: obj = ob.toString();
234: }
235:
236: }
237:
238: public void testToString() throws IOException, SAXException {
239:
240: String testcase = "<rdf:RDF xmlns:music=\"http://www.kanzaki.com/ns/music#\" "
241: + " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"> "
242: + "<rdf:Description> "
243: + " <music:performs rdf:nodeID=\"p1\"/> "
244: + "</rdf:Description> "
245: + "<rdf:Description rdf:nodeID=\"p1\"> "
246: + " <music:opus>op.26</music:opus> "
247: + "</rdf:Description> " + "</rdf:RDF>";
248:
249: ARP parser = new ARP();
250: ToStringStatementHandler tssh = new ToStringStatementHandler();
251: parser.getHandlers().setStatementHandler(tssh);
252: parser.load(new StringReader(testcase),
253: "http://www.example.com");
254: assertEquals(tssh.subj, tssh.obj);
255: }
256:
257: public void testEncodingMismatch2() throws IOException {
258: FileReader r = new FileReader(
259: "testing/wg/rdf-charmod-literals/test001.rdf");
260:
261: subTestEncodingMismatch2(r);
262: }
263:
264: public void testEncodingMismatch3() throws IOException {
265: FileInputStream fin = new FileInputStream(
266: "testing/wg/rdf-charmod-literals/test001.rdf");
267: InputStreamReader r = null;
268: try {
269: r = new InputStreamReader(fin, "MS950");
270: } catch (java.io.UnsupportedEncodingException e) {
271: System.err
272: .println("WARNING: Encoding mismatch3 test not executed on platform without MS950 encoding.");
273:
274: return;
275: }
276:
277: subTestEncodingMismatch2(r);
278: }
279:
280: private void subTestEncodingMismatch2(InputStreamReader r) {
281: if (r.getEncoding().startsWith("UTF")) {
282: // see above for warning message.
283: return;
284: }
285: Model m = createMemModel();
286: RDFReader rdr = m.getReader();
287:
288: rdr.setErrorHandler(this );
289: expected = new int[] { WARN_ENCODING_MISMATCH,
290: ERR_ENCODING_MISMATCH };
291: rdr.read(m, r, "http://example.org/");
292:
293: checkExpected();
294: }
295:
296: public void testNullBaseParamOK() throws IOException {
297: Model m = createMemModel();
298: Model m1 = createMemModel();
299: RDFReader rdr = m.getReader();
300: FileInputStream fin = new FileInputStream(
301: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
302:
303: rdr.setErrorHandler(this );
304: expected = new int[] {};
305: rdr.read(m, fin, "http://example.org/");
306: fin.close();
307: fin = new FileInputStream(
308: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
309: rdr.read(m1, fin, null);
310: fin.close();
311: assertTrue("Base URI should have no effect.", m
312: .isIsomorphicWith(m1));
313: checkExpected();
314: }
315:
316: public void testDanBriXMLBase() throws IOException {
317: Model m = createMemModel();
318: Model m1 = createMemModel();
319: FileInputStream fin = new FileInputStream(
320: "testing/arp/xmlbase/danbri.rdf");
321:
322: m.read(fin, "http://wrong.example.org/");
323: fin.close();
324: fin = new FileInputStream("testing/arp/xmlbase/danbri.nt");
325:
326: m1.read(fin, "http://wrong.example.org/", "N-TRIPLE");
327: fin.close();
328: assertTrue("Dan Bri nested XML Base.", m.isIsomorphicWith(m1));
329: }
330:
331: public void testNullBaseParamError() throws IOException {
332: Model m = createMemModel();
333: RDFReader rdr = m.getReader();
334: FileInputStream fin = new FileInputStream(
335: "testing/wg/rdfms-difference-between-ID-and-about/test1.rdf");
336: rdr.setErrorHandler(this );
337: expected = new int[] { ERR_RESOLVING_URI_AGAINST_NULL_BASE,
338: WARN_RELATIVE_URI };
339: rdr.read(m, fin, null);
340: fin.close();
341: checkExpected();
342: }
343:
344: public void testEmptyBaseParamOK() throws IOException {
345: Model m = createMemModel();
346: Model m1 = createMemModel();
347: RDFReader rdr = m.getReader();
348: FileInputStream fin = new FileInputStream(
349: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
350:
351: rdr.setErrorHandler(this );
352: expected = new int[] {};
353: rdr.read(m, fin, "http://example.org/");
354: fin.close();
355: fin = new FileInputStream(
356: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
357: rdr.read(m1, fin, "");
358: fin.close();
359: assertTrue("Empty base URI should have no effect.["
360: + m1.toString() + "]", m.isIsomorphicWith(m1));
361: checkExpected();
362: }
363:
364: public void testEmptyBaseParamError() throws IOException {
365: Model m = createMemModel();
366: RDFReader rdr = m.getReader();
367: FileInputStream fin = new FileInputStream(
368: "testing/wg/rdfms-difference-between-ID-and-about/test1.rdf");
369: rdr.setErrorHandler(this );
370: expected = new int[] { WARN_RESOLVING_URI_AGAINST_EMPTY_BASE };
371: rdr.read(m, fin, "");
372: fin.close();
373: Model m1 = createMemModel();
374: m1.createResource("#foo").addProperty(RDF.value, "abc");
375: assertTrue("Empty base URI should produce relative URI.["
376: + m.toString() + "]", m.isIsomorphicWith(m1));
377: checkExpected();
378: }
379:
380: public void testBadBaseParamError() throws IOException {
381: Model m = createMemModel();
382: RDFReader rdr = m.getReader();
383: FileInputStream fin = new FileInputStream(
384: "testing/wg/rdfms-difference-between-ID-and-about/test1.rdf");
385: rdr.setErrorHandler(this );
386: expected = new int[] { WARN_MALFORMED_URI, WARN_MALFORMED_URI,
387: // WARN_RELATIVE_URI, ERR_RESOLVING_AGAINST_MALFORMED_BASE};
388: ERR_RESOLVING_AGAINST_MALFORMED_BASE };
389: rdr.read(m, fin, "http://jjc^3.org/demo.mp3");
390: fin.close();
391: Model m1 = createMemModel();
392: assertTrue("Bad base URI should produce no URIs in model.["
393: + m.toString() + "]", m.isIsomorphicWith(m1));
394: checkExpected();
395: }
396:
397: public void testBadBaseParamOK() throws IOException {
398: Model m = createMemModel();
399: Model m1 = createMemModel();
400: RDFReader rdr = m.getReader();
401: FileInputStream fin = new FileInputStream(
402: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
403:
404: rdr.setErrorHandler(this );
405: expected = new int[] { WARN_MALFORMED_URI };
406: rdr.read(m, fin, "http://jjc^3.org/demo.mp3");
407: fin.close();
408: fin = new FileInputStream(
409: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
410: rdr.read(m1, fin, "");
411: fin.close();
412: assertTrue("Bad base URI should have no effect on model.["
413: + m1.toString() + "]", m.isIsomorphicWith(m1));
414: checkExpected();
415: }
416:
417: public void testRelativeBaseParamError() throws IOException {
418: Model m = createMemModel();
419: RDFReader rdr = m.getReader();
420: FileInputStream fin = new FileInputStream(
421: "testing/wg/rdfms-difference-between-ID-and-about/test1.rdf");
422: rdr.setErrorHandler(this );
423: expected = new int[] { WARN_RELATIVE_URI, WARN_RELATIVE_URI,
424: ERR_RESOLVING_AGAINST_RELATIVE_BASE, };
425: rdr.setProperty("ERR_RESOLVING_AGAINST_RELATIVE_BASE",
426: "EM_WARNING");
427: rdr.read(m, fin, "foo/");
428: fin.close();
429: Model m1 = createMemModel();
430: m1.createResource("foo/#foo").addProperty(RDF.value, "abc");
431: assertTrue(
432: "Relative base URI should produce relative URIs in model (when error suppressed).["
433: + m.toString() + "]", m.isIsomorphicWith(m1));
434: checkExpected();
435: }
436:
437: public void testRelativeBaseParamOK() throws IOException {
438: Model m = createMemModel();
439: Model m1 = createMemModel();
440: RDFReader rdr = m.getReader();
441: FileInputStream fin = new FileInputStream(
442: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
443:
444: rdr.setErrorHandler(this );
445: expected = new int[] { WARN_RELATIVE_URI };
446: rdr.read(m, fin, "foo/");
447: fin.close();
448: fin = new FileInputStream(
449: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
450: rdr.read(m1, fin, "");
451: fin.close();
452: assertTrue("Bad base URI should have no effect on model.["
453: + m1.toString() + "]", m.isIsomorphicWith(m1));
454: checkExpected();
455: }
456:
457: public void testBaseTruncation() throws IOException {
458: Model m = createMemModel();
459: Model m1 = createMemModel();
460: RDFReader rdr = m.getReader();
461: FileInputStream fin = new FileInputStream(
462: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
463:
464: rdr.setErrorHandler(this );
465: expected = new int[] { WARN_MALFORMED_URI, WARN_RELATIVE_URI };
466: rdr.read(m, fin, "ht#tp://jjc3.org/demo.mp3#frag");
467: fin.close();
468: fin = new FileInputStream(
469: "testing/wg/rdfms-identity-anon-resources/test001.rdf");
470: rdr.read(m1, fin, "");
471: fin.close();
472: assertTrue("Bad base URI should have no effect.["
473: + m1.toString() + "]", m.isIsomorphicWith(m1));
474: checkExpected();
475: }
476:
477: public void testInterrupt() throws SAXException, IOException {
478: ARP a = new ARP();
479: InputStream in;
480: // long start = System.currentTimeMillis();
481: in = new FileInputStream(
482: "testing/wg/miscellaneous/consistent001.rdf");
483: a.getHandlers().setStatementHandler(new StatementHandler() {
484: int countDown = 10;
485:
486: public void statement(AResource subj, AResource pred,
487: AResource obj) {
488: if (countDown-- == 0)
489: Thread.currentThread().interrupt();
490:
491: }
492:
493: public void statement(AResource subj, AResource pred,
494: ALiteral lit) {
495:
496: }
497: });
498: a.getHandlers().setErrorHandler(new ErrorHandler() {
499: public void error(SAXParseException exception)
500: throws SAXException {
501: throw new RuntimeException("Unexpected error",
502: exception);
503: }
504:
505: public void fatalError(SAXParseException exception)
506: throws SAXException {
507: throw exception;
508: }
509:
510: public void warning(SAXParseException exception)
511: throws SAXException {
512: throw new RuntimeException("Unexpected warning",
513: exception);
514: }
515: });
516: try {
517: a.load(in);
518: fail("Thread was not interrupted.");
519: } catch (InterruptedIOException e) {
520: } catch (SAXParseException e) {
521: } finally {
522: in.close();
523: }
524: // System.err.println("Finished "+Thread.interrupted());
525:
526: }
527:
528: private void checkExpected() {
529: for (int i = 0; i < expected.length; i++)
530: if (expected[i] != 0) {
531: fail("Expected error: "
532: + ParseException.errorCodeName(expected[i])
533: + " but it did not occur.");
534: }
535: }
536:
537: public void warning(Exception e) {
538: error(0, e);
539: }
540:
541: public void error(Exception e) {
542: error(1, e);
543: }
544:
545: public void fatalError(Exception e) {
546: error(2, e);
547: }
548:
549: private void error(int level, Exception e) {
550: //System.err.println(e.getMessage());
551: if (e instanceof ParseException) {
552: int eCode = ((ParseException) e).getErrorNumber();
553: onError(level, eCode);
554: } else {
555: fail("Not expecting an Exception: " + e.getMessage());
556: }
557: }
558:
559: private int expected[];
560:
561: private void println(String m) {
562: logger.error(m);
563: }
564:
565: void onError(int level, int num) {
566: for (int i = 0; i < expected.length; i++)
567: if (expected[i] == num) {
568: expected[i] = 0;
569: return;
570: }
571: String msg = "Parser reports unexpected "
572: + WGTestSuite.errorLevelName[level] + ": "
573: + ParseException.errorCodeName(num);
574: println(msg);
575: fail(msg);
576: }
577:
578: // private void tokenGarbage(String file) {
579: // try {
580: // Token.COUNT = true;
581: // Token.COUNTTEST = true;
582: // Token.reinitHighTide();
583: // NTriple.main(new String[] { "-t", file });
584: // //System.err.println("["+Token.highTide+"]");
585: // assertTrue("Too many tokens used: "+ Token.highTide,
586: // Token.highTide<2000);
587: // } finally {
588: // Token.COUNT = false;
589: // Token.COUNTTEST = false;
590: // }
591: // }
592: //
593: // public void testTokenGarbage1() {
594: // tokenGarbage("testing/ontology/owl/Wine/wine.owl");
595: // }
596: //
597: // public void testTokenGarbage2() {
598: //
599: // tokenGarbage("testing/arp/gc/someWordNet.rdf");
600: // }
601: }
602:
603: /*
604: * (c) Copyright 2000, 2001, 2002, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
605: * All rights reserved.
606: *
607: * Redistribution and use in source and binary forms, with or without
608: * modification, are permitted provided that the following conditions are met:
609: *
610: * 1. Redistributions of source code must retain the above copyright notice,
611: * this list of conditions and the following disclaimer.
612: *
613: * 2. Redistributions in binary form must reproduce the above copyright notice,
614: * this list of conditions and the following disclaimer in the documentation
615: * and/or other materials provided with the distribution.
616: *
617: * 3. The name of the author may not be used to endorse or promote products
618: * derived from this software without specific prior written permission.
619: *
620: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
621: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
622: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
623: * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
624: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
625: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
626: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
627: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
628: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
629: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
630: */
|