KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > dig > test > WebOntTests


1 /*****************************************************************************
2  * Source code information
3  * -----------------------
4  * Original author Ian Dickinson, HP Labs Bristol
5  * Author email ian.dickinson@hp.com
6  * Package @package@
7  * Web site http://jena.sourceforge.net/
8  * Created 20-Apr-2004
9  * Filename $RCSfile: WebOntTests.java,v $
10  * Revision $Revision: 1.9 $
11  * Release status $State: Exp $
12  *
13  * Last modified on $Date: 2005/02/21 12:16:34 $
14  * by $Author: andy_seaborne $
15  *
16  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
17  *****************************************************************************/

18
19 // Package
20
///////////////
21

22 package com.hp.hpl.jena.reasoner.dig.test;
23
24
25 // Imports
26
///////////////
27
import com.hp.hpl.jena.graph.query.*;
28 import com.hp.hpl.jena.graph.*;
29 import com.hp.hpl.jena.ontology.*;
30 import com.hp.hpl.jena.ontology.OntDocumentManager;
31 import com.hp.hpl.jena.ontology.OntModelSpec;
32 import com.hp.hpl.jena.rdf.model.*;
33 import com.hp.hpl.jena.reasoner.*;
34 import com.hp.hpl.jena.reasoner.dig.*;
35 import com.hp.hpl.jena.reasoner.dig.DIGReasoner;
36 import com.hp.hpl.jena.reasoner.dig.DIGReasonerFactory;
37 import com.hp.hpl.jena.reasoner.test.WGReasonerTester;
38 import com.hp.hpl.jena.util.iterator.ExtendedIterator;
39 import com.hp.hpl.jena.vocabulary.*;
40
41 import java.io.*;
42 import java.util.*;
43
44 import org.apache.commons.logging.LogFactory;
45
46
47
48 /**
49  * <p>
50  * Test harness for running the WebOnt working group tests on the DIG reasoner
51  * interface. This class is derived from Dave's
52  * {@link com.hp.hpl.jena.reasoner.rulesys.test.WebOntTestHarness WebOntTestHarness}.
53  * </p>
54  *
55  * @author Ian Dickinson, HP Labs ( <a HREF="mailto:Ian.Dickinson@hp.com">email
56  * </a>)
57  * @version Release @release@ ($Id: eclipse-template.txt,v 1.2 2003/10/20
58  * 22:03:02 ian_dickinson Exp $)
59  */

60 public class WebOntTests
61 {
62     // Constants
63
//////////////////////////////////
64

65     /** The base directory for the working group test files to use */
66     public static final String JavaDoc BASE_TESTDIR = "testing/wg/";
67
68     /** The base URI in which the files are purported to reside */
69     public static String JavaDoc BASE_URI = "http://www.w3.org/2002/03owlt/";
70
71     /** The namespace for terms in the owl test ontology */
72     public static final String JavaDoc OTEST_NS = BASE_URI + "testOntology#";
73     
74     /** The base URI for the results file */
75     public static String JavaDoc BASE_RESULTS_URI = "http://jena.sourceforge.net/data/owl-results.rdf";
76
77     /** The list of subdirectories to process (omits the rdf/rdfs dirs) */
78     public static final String JavaDoc[] TEST_DIRS = {
79             "AllDifferent",
80             "AnnotationProperty",
81             "DatatypeProperty",
82             "FunctionalProperty",
83             "I3.2",
84             "I3.4",
85             "I4.1",
86             "I4.5",
87             "I4.6",
88             "I5.1",
89             "I5.2",
90             "I5.21",
91             "I5.24",
92             "I5.26",
93             "I5.3",
94             "I5.5",
95             "I5.8",
96             "InverseFunctionalProperty",
97             "Nothing",
98             "Restriction",
99             "SymmetricProperty",
100             "Thing",
101             "TransitiveProperty",
102             "Class",
103             "allValuesFrom",
104             "amp-in-url",
105             "cardinality",
106             "complementOf",
107             "datatypes",
108             "differentFrom",
109             "disjointWith",
110             "distinctMembers",
111             "equivalentClass",
112             "equivalentProperty",
113             "imports",
114             "intersectionOf",
115             "inverseOf",
116             "localtests",
117             "maxCardinality",
118             "miscellaneous",
119             "oneOf",
120             "sameAs",
121             "someValuesFrom",
122             "statement-entailment",
123             "unionOf",
124             "xmlbase",
125             "description-logic",
126              "extra-credit",
127     };
128
129     /**
130      * List of tests that are blocked because they test language features
131      * beyond OWL DL
132      */

133     public static final String JavaDoc[] BLOCKED_TESTS = {};
134
135     /**
136      * The list of status values to include. If approvedOnly then only the
137      * first entry is allowed
138      */

139     public static final String JavaDoc[] STATUS_FLAGS = {"APPROVED", "PROPOSED"};
140
141     /** List of acceptable test levels */
142     public static final List ACCEPTABLE_TEST_LEVELS = Arrays.asList( new Resource[] {OWLTest.Lite, OWLTest.DL} );
143     
144     /** List of predicates we don't want in the premises (because we will try to prove them) */
145     protected static List UNSAFE_PREMISE_PREDICATES = new ArrayList();
146     static {
147         UNSAFE_PREMISE_PREDICATES.add( OWL.equivalentClass );
148         UNSAFE_PREMISE_PREDICATES.add( OWL.equivalentProperty);
149         UNSAFE_PREMISE_PREDICATES.add( OWL.sameAs );
150         UNSAFE_PREMISE_PREDICATES.add( RDFS.subClassOf );
151         UNSAFE_PREMISE_PREDICATES.add( RDFS.subPropertyOf );
152         UNSAFE_PREMISE_PREDICATES.add( DAML_OIL.sameClassAs );
153         UNSAFE_PREMISE_PREDICATES.add( DAML_OIL.sameIndividualAs );
154         UNSAFE_PREMISE_PREDICATES.add( DAML_OIL.samePropertyAs );
155         UNSAFE_PREMISE_PREDICATES.add( DAML_OIL.subClassOf );
156         UNSAFE_PREMISE_PREDICATES.add( DAML_OIL.subPropertyOf );
157     }
158     
159     
160     // Static variables
161
//////////////////////////////////
162

163     /** Set to true to include modified test versions */
164     protected static boolean s_includeModified = false;
165
166     /** Set to true to use approved tests only */
167     protected static boolean s_approvedOnly = true;
168
169
170     // Instance variables
171
//////////////////////////////////
172

173     /** The reasoner being tested */
174     private DIGReasoner m_reasoner;
175
176     /** The total set of known tests */
177     private Model m_testDefinitions;
178
179     /** The number of tests run */
180     private int m_testCount = 0;
181
182     /** The time cost in ms of the last test to be run */
183     private long m_lastTestDuration = 0;
184
185     /** Number of tests passed */
186     private int m_passCount = 0;
187
188     /** The model describing the results of the run */
189     private Model m_testResults;
190
191     /**
192      * The resource which acts as a description for the Jena2 instance being
193      * tested
194      */

195     private Resource m_jena2;
196
197
198     // Constructors
199
//////////////////////////////////
200

201     public WebOntTests() {
202         m_testDefinitions = loadAllTestDefinitions();
203         DIGReasonerFactory drf = (DIGReasonerFactory) ReasonerRegistry.theRegistry().getFactory( DIGReasonerFactory.URI );
204         m_reasoner = (DIGReasoner) drf.createWithOWLAxioms( null );
205         initResults();
206     }
207
208     
209     // External signature methods
210
//////////////////////////////////
211

212     public static void main( String JavaDoc[] args ) throws IOException {
213         String JavaDoc resultFile = "owl-results.rdf";
214         String JavaDoc testName = null;
215         
216         if (args.length >= 1) {
217             testName = args[0];
218         }
219
220         WebOntTests harness = new WebOntTests();
221         
222         // initialise the document manager
223
OntDocumentManager.getInstance().addAltEntry( "http://www.w3.org/2002/03owlt/miscellaneous/consistent002",
224                                                         "file:testing/wg/miscellaneous/consistent002.rdf" );
225         OntDocumentManager.getInstance().addAltEntry( "http://www.w3.org/2002/03owlt/miscellaneous/consistent001",
226                                                         "file:testing/wg/miscellaneous/consistent001.rdf" );
227
228         if (testName == null) {
229             harness.runTests();
230         }
231         else {
232             harness.runTest( testName );
233         }
234
235         RDFWriter writer = harness.m_testResults.getWriter("RDF/XML-ABBREV");
236         OutputStream stream = new FileOutputStream(resultFile);
237         writer.setProperty("showXmlDeclaration", "true");
238         harness.m_testResults.setNsPrefix("", "http://www.w3.org/1999/xhtml");
239         writer.write(harness.m_testResults, stream, BASE_RESULTS_URI);
240     }
241
242     /**
243      * Run all relevant tests.
244      */

245     public void runTests() {
246         System.out.println("Testing " + (s_approvedOnly ? "only APPROVED" : "APPROVED and PROPOSED"));
247         System.out.println("Positive entailment: ");
248         runTests(findTestsOfType(OWLTest.PositiveEntailmentTest));
249         System.out.println("\nNegative entailment: ");
250         runTests(findTestsOfType(OWLTest.NegativeEntailmentTest));
251         System.out.println("\nTrue tests: ");
252         runTests(findTestsOfType(OWLTest.TrueTest));
253         System.out.println("\nOWL for OWL tests: ");
254         runTests(findTestsOfType(OWLTest.OWLforOWLTest));
255         System.out.println("\nImport entailment tests: ");
256         runTests(findTestsOfType(OWLTest.ImportEntailmentTest));
257         System.out.println("\nInconsistency tests: ");
258         runTests(findTestsOfType(OWLTest.InconsistencyTest));
259         System.out.println("\nPassed " + m_passCount + " out of " + m_testCount);
260     }
261
262     /**
263      * Run all tests in the given list.
264      */

265     public void runTests( List tests ) {
266         for (Iterator i = tests.iterator(); i.hasNext();) {
267             runTest((Resource) i.next());
268         }
269     }
270
271     /**
272      * Run a single test of any sort, performing any appropriate logging and
273      * error reporting.
274      */

275     public void runTest( String JavaDoc test ) {
276         runTest(m_testDefinitions.getResource(test));
277     }
278
279     /**
280      * Run a single test of any sort, performing any appropriate logging and
281      * error reporting.
282      */

283     public void runTest( Resource test ) {
284         System.out.println("Running " + test);
285         boolean success = false;
286         boolean fail = false;
287         try {
288             success = doRunTest(test);
289         }
290         catch (Exception JavaDoc e) {
291             fail = true;
292             System.err.print("\nException: " + e);
293             e.printStackTrace();
294         }
295         m_testCount++;
296         
297         if (success) {
298             System.out.print((m_testCount % 40 == 0) ? ".\n" : ".");
299             System.out.flush();
300             m_passCount++;
301         }
302         else {
303             System.out.println("\nFAIL: " + test);
304         }
305         Resource resultType = null;
306         
307         if (fail) {
308             resultType = OWLResults.FailingRun;
309         }
310         else {
311             if (test.hasProperty(RDF.type, OWLTest.NegativeEntailmentTest)
312                     || test.hasProperty(RDF.type, OWLTest.ConsistencyTest)) {
313                 resultType = success ? OWLResults.PassingRun : OWLResults.FailingRun;
314             }
315             else {
316                 resultType = success ? OWLResults.PassingRun : OWLResults.IncompleteRun;
317             }
318         }
319         
320         // log to the rdf result format
321
Resource result = m_testResults.createResource()
322                                        .addProperty(RDF.type, OWLResults.TestRun)
323                                        .addProperty(RDF.type, resultType)
324                                        .addProperty(OWLResults.test, test)
325                                        .addProperty(OWLResults.system, m_jena2);
326     }
327
328     /**
329      * Run a single test of any sort, return true if the test succeeds.
330      */

331     public boolean doRunTest( Resource test )
332         throws IOException
333     {
334         if (test.hasProperty(RDF.type, OWLTest.PositiveEntailmentTest)
335                 || test.hasProperty(RDF.type, OWLTest.NegativeEntailmentTest)
336                 || test.hasProperty(RDF.type, OWLTest.OWLforOWLTest)
337                 || test.hasProperty(RDF.type, OWLTest.ImportEntailmentTest)
338                 || test.hasProperty(RDF.type, OWLTest.TrueTest)) {
339             // Entailment tests
340
System.out.println("Starting: " + test);
341             boolean processImports = test.hasProperty( RDF.type, OWLTest.ImportEntailmentTest );
342             Model premises = getDoc( test, RDFTest.premiseDocument, processImports );
343             Model conclusions = getDoc( test, RDFTest.conclusionDocument );
344             
345             long t1 = System.currentTimeMillis();
346             boolean correct = testEntailment( conclusions, m_reasoner.bind( premises.getGraph() ) );
347             m_lastTestDuration = System.currentTimeMillis() - t1;
348
349             if (test.hasProperty(RDF.type, OWLTest.NegativeEntailmentTest)) {
350                 correct = !correct;
351             }
352             return correct;
353         }
354         else if (test.hasProperty(RDF.type, OWLTest.InconsistencyTest)) {
355             System.out.println("Starting: " + test);
356             Model input = getDoc(test, RDFTest.inputDocument);
357             long t1 = System.currentTimeMillis();
358             InfGraph graph = m_reasoner.bind(input.getGraph());
359             boolean correct = !graph.validate().isValid();
360             m_lastTestDuration = System.currentTimeMillis() - t1;
361             return correct;
362         }
363         else if (test.hasProperty(RDF.type, OWLTest.ConsistencyTest)) {
364             System.out.println("Starting: " + test);
365             Model input = getDoc(test, RDFTest.inputDocument);
366             long t1 = System.currentTimeMillis();
367             InfGraph graph = m_reasoner.bind(input.getGraph());
368             boolean correct = graph.validate().isValid();
369             long t2 = System.currentTimeMillis();
370             m_lastTestDuration = t2 - t1;
371             return correct;
372         }
373         else {
374             for (StmtIterator i = test.listProperties(RDF.type); i.hasNext();) {
375                 System.out.println("Test type = " + i.nextStatement().getObject());
376             }
377             throw new ReasonerException("Unknown test type");
378         }
379     }
380
381     /**
382      * Load the premises or conclusions for the test, optional performing
383      * import processing.
384      */

385     public Model getDoc( Resource test, Property docType, boolean processImports ) throws IOException {
386         if (processImports) {
387             Model result = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null);
388             StmtIterator si = test.listProperties(docType);
389             while (si.hasNext()) {
390                 String JavaDoc fname = si.nextStatement().getObject().toString() + ".rdf";
391                 loadFile(fname, result);
392             }
393             return result;
394         }
395         else {
396             return getDoc(test, docType);
397         }
398     }
399
400     /**
401      * Load the premises or conclusions for the test.
402      */

403     public Model getDoc( Resource test, Property docType ) throws IOException {
404         Model result = ModelFactory.createDefaultModel();
405         StmtIterator si = test.listProperties(docType);
406         while (si.hasNext()) {
407             String JavaDoc fname = si.nextStatement().getObject().toString() + ".rdf";
408             loadFile(fname, result);
409         }
410         return result;
411     }
412
413     /**
414      * Utility to load a file into a model a Model. Files are assumed to be
415      * relative to the BASE_URI.
416      *
417      * @param file the file name, relative to baseDir
418      * @return the loaded Model
419      */

420     public static Model loadFile( String JavaDoc file, Model model ) throws IOException {
421         String JavaDoc langType = "RDF/XML";
422         if (file.endsWith(".nt")) {
423             langType = "N-TRIPLE";
424         }
425         else if (file.endsWith("n3")) {
426             langType = "N3";
427         }
428         String JavaDoc fname = file;
429         if (fname.startsWith(BASE_URI)) {
430             fname = fname.substring(BASE_URI.length());
431         }
432         Reader reader = new BufferedReader(new FileReader(BASE_TESTDIR + fname));
433         model.read(reader, BASE_URI + fname, langType);
434         return model;
435     }
436
437     /**
438      * Test a conclusions graph against a result graph. This works by
439      * translating the conclusions graph into a find query which contains one
440      * variable for each distinct bNode in the conclusions graph.
441      */

442     public boolean testEntailment( Model conclusions, InfGraph inf ) {
443         List queryRoots = listQueryRoots( conclusions );
444         Model result = ModelFactory.createDefaultModel();
445         
446         for (Iterator i = queryRoots.iterator(); i.hasNext(); ) {
447             Resource root = (Resource) i.next();
448             
449             for (StmtIterator j = root.listProperties(); j.hasNext(); ) {
450                 Statement rootQuery = j.nextStatement();
451                 Resource subject = rootQuery.getSubject();
452                 RDFNode object = rootQuery.getObject();
453                 
454                 OntModel premises = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null );
455                 premises.setStrictMode( false );
456                 
457                 if (subject.isAnon()) {
458                     // subject is assumed to be an expression
459
addSubGraph( subject, premises );
460                 }
461                 if (object instanceof Resource && ((Resource) object).isAnon()) {
462                     addSubGraph( (Resource) object, premises );
463                 }
464                 
465                 // add the resulting triples to the graph
466
try {
467                     ExtendedIterator k =inf.find( rootQuery.getSubject().asNode(),
468                                                   rootQuery.getPredicate().asNode(),
469                                                   rootQuery.getObject().asNode(),
470                                                   premises.getGraph() );
471                     while (k.hasNext()) {
472                         //Triple t = (Triple) k.next();
473
Object JavaDoc x = k.next();
474                         Triple t = (Triple) x;
475                         LogFactory.getLog( getClass() ).debug( "testEntailment got triple " + t );
476                         result.getGraph().add( t );
477                     }
478                     
479                     // transcribe the premises into the results
480
result.add( premises );
481                 }
482                 catch (DIGErrorResponseException e) {
483                     LogFactory.getLog( getClass() ).error( "DIG reasoner returned error: " + e.getMessage() );
484                     return false;
485                 }
486             }
487         }
488         
489         result.write( System.out, "RDF/XML-ABBREV" );
490         // now check that the conclusions, framed as a query, holds
491
QueryHandler qh = result.queryHandler();
492         Query query = WGReasonerTester.graphToQuery(conclusions.getGraph());
493         Iterator i = qh.prepareBindings(query, new Node[] {}).executeBindings();
494         return i.hasNext();
495     }
496
497
498
499     // Internal implementation methods
500
//////////////////////////////////
501

502     /** Load all of the known manifest files into a single model */
503     protected Model loadAllTestDefinitions() {
504         System.out.print("Loading manifests ");
505         System.out.flush();
506         Model testDefs = ModelFactory.createDefaultModel();
507         int count = 0;
508         for (int idir = 0; idir < TEST_DIRS.length; idir++) {
509             File dir = new File(BASE_TESTDIR + TEST_DIRS[idir]);
510             String JavaDoc[] manifests = dir.list(new FilenameFilter() {
511                 public boolean accept( File df, String JavaDoc name ) {
512                     return name.startsWith("Manifest") && name.endsWith(".rdf") &&
513                             (s_includeModified || !name.endsWith("-mod.rdf"));
514                 }
515             });
516             if (manifests == null) {
517                 System.err.println( "No manifests for " + BASE_TESTDIR + TEST_DIRS[idir] );
518             }
519             else {
520                 for (int im = 0; im < manifests.length; im++) {
521                     String JavaDoc manifest = manifests[im];
522                     File mf = new File(dir, manifest);
523                     try {
524                         testDefs.read(new FileInputStream(mf), "file:" + mf);
525                         count++;
526                         if (count % 8 == 0) {
527                             System.out.print(".");
528                             System.out.flush();
529                         }
530                     }
531                     catch (FileNotFoundException e) {
532                         System.out.println("File not readable - " + e);
533                     }
534                 }
535             }
536         }
537         System.out.println("loaded");
538         return testDefs;
539     }
540
541     /**
542      * Initialize the result model.
543      */

544     protected void initResults() {
545         m_testResults = ModelFactory.createDefaultModel();
546         m_jena2 = m_testResults.createResource(BASE_RESULTS_URI + "#jena2");
547         m_jena2
548                 .addProperty(
549                         RDFS.comment,
550                         m_testResults
551                                 .createLiteral(
552                                         "<a xmlns=\"http://www.w3.org/1999/xhtml\" HREF=\"http://jena.sourceforce.net/\">Jena2</a> includes a rule-based inference engine for RDF processing, "
553                                                 + "supporting both forward and backward chaining rules. Its OWL rule set is designed to provide sound "
554                                                 + "but not complete instance resasoning for that fragment of OWL/Full limited to the OWL/lite vocabulary. In"
555                                                 + "particular it does not support unionOf/complementOf.", true));
556         m_jena2.addProperty(RDFS.label, "Jena2");
557         m_testResults.setNsPrefix("results", OWLResults.NS);
558     }
559
560
561     /**
562      * Return a list of all tests of the given type, according to the current
563      * filters
564      */

565     public List findTestsOfType( Resource testType ) {
566         ArrayList result = new ArrayList();
567         StmtIterator si = m_testDefinitions.listStatements(null, RDF.type, testType);
568         while (si.hasNext()) {
569             Resource test = si.nextStatement().getSubject();
570             boolean accept = true;
571             
572             // Check test status
573
Literal status = (Literal) test.getProperty(RDFTest.status).getObject();
574             if (s_approvedOnly) {
575                 accept = status.getString().equals(STATUS_FLAGS[0]);
576             }
577             else {
578                 accept = false;
579                 for (int i = 0; i < STATUS_FLAGS.length; i++) {
580                     if (status.getString().equals(STATUS_FLAGS[i])) {
581                         accept = true;
582                         break;
583                     }
584                 }
585             }
586             
587             // Check for blocked tests
588
for (int i = 0; i < BLOCKED_TESTS.length; i++) {
589                 if (BLOCKED_TESTS[i].equals(test.toString())) {
590                     accept = false;
591                 }
592             }
593             
594             // Check test level
595
if (accept) {
596                 boolean reject = true;
597                 for (StmtIterator i = test.listProperties( OWLTest.level ); i.hasNext(); ) {
598                     if (ACCEPTABLE_TEST_LEVELS.contains( i.nextStatement().getResource() )) {
599                         reject = false;
600                     }
601                 }
602                 
603                 if (reject) {
604                     LogFactory.getLog( getClass() ).debug( "Ignoring test " + test + " because it either has no test level defined, or an unacceptable test level" );
605                     accept = false;
606                 }
607             }
608             
609             // End of filter tests
610
if (accept) {
611                 result.add(test);
612             }
613         }
614         return result;
615     }
616
617     /**
618      * The query roots of are the set of subjects we want to ask the DIG
619      * reasoner about ... we interpret this as every named resource in the given model
620      */

621     protected List listQueryRoots( Model m ) {
622         Set seen = new HashSet();
623         List q = new ArrayList();
624         List roots = new ArrayList();
625         
626         for (ResIterator i = m.listSubjects(); i.hasNext(); ) {
627             Resource subj = i.nextResource();
628             if (!subj.isAnon()) {
629                 roots.add( subj );
630             }
631         }
632
633         for (Iterator i = roots.iterator(); i.hasNext(); ) {
634             LogFactory.getLog( getClass() ).debug( "Found query root: " + i.next() );
635         }
636         return roots;
637     }
638     
639     /**
640      * Add the reachable sub-graph from root, unless it traverses a predicate
641      * that we might be trying to establish.
642      * @param root
643      * @param premises
644      */

645     protected void addSubGraph( Resource root, Model premises ) {
646         List q = new ArrayList();
647         Set seen = new HashSet();
648         q.add( root );
649         
650         while (!q.isEmpty()) {
651             Resource r = (Resource) q.remove( 0 );
652             
653             if (!seen.contains( r )) {
654                 for (StmtIterator i = r.listProperties(); i.hasNext(); ) {
655                     Statement s = i.nextStatement();
656                     
657                     if (safePremise( s.getPredicate() )) {
658                         premises.add( s );
659                         if (s.getObject() instanceof Resource) {
660                             q.add( s.getObject() );
661                         }
662                     }
663                 }
664                 seen.add( r );
665             }
666         }
667     }
668     
669     /**
670      * <p>Answer true if p is a property that is safe to add as a premise without
671      * assertng what we are trying to find out. Properties ruled out by this
672      * test are owl:equivalentClass, owl:equivalentProperty, etc.
673      * @param p A property to test
674      * @return True if p is safe to add to the premises
675      */

676     protected boolean safePremise( Property p ) {
677         return !(UNSAFE_PREMISE_PREDICATES.contains( p ));
678     }
679     
680     
681     //==============================================================================
682
// Inner class definitions
683
//==============================================================================
684

685 }
686
687
688 /*
689  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
690  * All rights reserved.
691  *
692  * Redistribution and use in source and binary forms, with or without
693  * modification, are permitted provided that the following conditions are met:
694  * 1. Redistributions of source code must retain the above copyright notice,
695  * this list of conditions and the following disclaimer.
696  * 2. Redistributions in binary form must reproduce the above copyright
697  * notice, this list of conditions and the following disclaimer in the
698  * documentation and/or other materials provided with the distribution.
699  * 3. The name of the author may not be used to endorse or promote products
700  * derived from this software without specific prior written permission.
701  *
702  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
703  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
704  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
705  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
706  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
707  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
708  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
709  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
710  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
711  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
712  */

713
Popular Tags