TestCreole.java
001 /*
002  *  TestCreole.java
003  *
004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Hamish Cunningham, 16/Mar/00
013  *
014  *  $Id: TestCreole.java 12006 2009-12-01 17:24:28Z thomas_heitz $
015  */
016 
017 package gate.creole;
018 
019 import java.beans.*;
020 import java.lang.reflect.Method;
021 import java.net.URL;
022 import java.util.*;
023 
024 import junit.framework.*;
025 
026 import gate.*;
027 import gate.util.GateException;
028 import gate.util.Out;
029 
030 /** CREOLE test class
031   */
032 public class TestCreole extends TestCase
033 {
034   /** Debug flag */
035   private static final boolean DEBUG = false;
036 
037   /** Construction */
038   public TestCreole(String namethrows GateException super(name)}
039 
040   /** Local shorthand for the CREOLE register */
041   private CreoleRegister reg;
042 
043   /** Fixture set up */
044   public void setUp() throws Exception {
045     // Initialise the GATE library and creole register
046     Gate.init();
047 
048     // clear the register and the creole directory set
049     reg = Gate.getCreoleRegister();
050     reg.clear();
051 
052     // find a URL for finding test files and add to the directory set
053     URL testUrl = Gate.getUrl("tests/");
054 //    reg.registerDirectories(testUrl);
055     reg.addDirectory(testUrl);
056     reg.registerDirectories();
057     
058     if(DEBUG) {
059       Iterator iter = reg.values().iterator();
060       while(iter.hasNext()) Out.println(iter.next());
061     }
062   // setUp
063 
064   /** Put things back as they should be after running tests
065     * (reinitialise the CREOLE register).
066     */
067   public void tearDown() throws Exception {
068     reg.clear();
069     Gate.init();
070   // tearDown
071 
072   /** Test the getInstances methods on CreoleRegister */
073   public void testInstanceLists() throws Exception {
074     // misc locals
075     List l;
076     CreoleRegister cr = Gate.getCreoleRegister();
077     Iterator iter;
078     ResourceData resData = null;
079     Resource res = null;
080     int numLrInstances = 0;
081 
082     // Get the lists of types
083     Set vrTypes = reg.getVrTypes();
084     Set prTypes = reg.getPrTypes();
085     Set lrTypes = reg.getLrTypes();
086 
087     // The only instances of any type should be autoloading ones
088     l = cr.getVrInstances();
089     if(! allAutoloaders(l))
090       fail(" non-autoloading resources already present (1)");
091     l = cr.getLrInstances();
092     numLrInstances = l.size();
093     if(! allAutoloaders(l))
094       fail(" non-autoloading resources already present (2)");
095     l = cr.getPrInstances();
096     if(! allAutoloaders(l))
097       fail(" non-autoloading resources already present (3)");
098 
099     // Create an LR
100     FeatureMap params = Factory.newFeatureMap();
101     params.put("features", Factory.newFeatureMap());
102     params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html")
103     );
104     res = Factory.createResource("gate.corpora.DocumentImpl", params);
105 
106     // lr instances list should be one longer now
107     if((cr.getLrInstances().size() == numLrInstances + 1))
108       fail("wrong number of LRs");
109 
110     // Create another LR
111     params = Factory.newFeatureMap();
112     params.put("features", Factory.newFeatureMap());
113     params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html")
114     );
115     res = Factory.createResource("gate.corpora.DocumentImpl", params);
116 
117     // lr instances list should be two longer now
118     if((cr.getLrInstances().size() == numLrInstances + 2))
119       fail("wrong number of LRs");
120 
121     // we should have two instances of type document
122     l = cr.getLrInstances("gate.corpora.DocumentImpl");
123     if(l.size() != 2)
124       fail("wrong number of documents");
125   // testInstanceLists
126 
127 
128   /** Test view registration */
129   public void testViews() throws Exception {
130     List smallViews1 =
131                   reg.getSmallVRsForResource("gate.persist.SerialDataStore");
132     String className1 = new String("");
133     if (smallViews1!= null && smallViews1.size()>0)
134       className1 = (String)smallViews1.get(0);
135     assertTrue(
136       "Found "+className1+
137       " as small viewer for gate.persist.SerialDataStore, "+
138       "instead  of gate.gui.SerialDatastoreViewer",
139       smallViews1.size() == &&
140       "gate.gui.SerialDatastoreViewer".equals(className1)
141     );
142 
143     List largeViews1 =
144                   reg.getLargeVRsForResource("gate.Corpus");
145     assertTrue(
146       "Found "+largeViews1.size()+" wich are " +largeViews1 +
147       " as large viewers for gate.Corpus, "+
148      "instead  of 2 which are [gate.gui.CorpusEditor, gate.gui.FeaturesEditor]",
149       largeViews1.size() == 2
150     );
151 
152     List largeViews2 =
153                   reg.getLargeVRsForResource("gate.Document");
154     assertTrue(
155       "Found "+largeViews2.size()+" wich are " +largeViews2 +
156       " as large viewers for gate.Document, "+
157      "instead  of 2 which are [gate.gui.DocumentEditor, gate.gui.FeaturesEditor]",
158       largeViews2.size() == 2
159     );
160 
161     List annotViews1 =
162                   reg.getAnnotationVRs();
163     assertTrue(
164       "Found "+annotViews1.size()+" wich are " +annotViews1 +
165       " as annotation viewers for all types annotations, "+
166      "instead  of 2 which are [gate.gui.SchemaAnnotationEditor,"+
167      " gate.gui.UnrestrictedAnnotationEditor]",
168       annotViews1.size() == 2
169     );
170   // testViews()
171 
172   /** Utility method to check that a list of resources are all
173     * auto-loading.
174     */
175   protected boolean allAutoloaders(List l) {
176     if(l != null) {
177       Resource res = null;
178       ResourceData resData = null;
179       CreoleRegister cr = Gate.getCreoleRegister();
180       Iterator iter = l.iterator();
181       while(iter.hasNext()) {
182         res = (Resourceiter.next();
183         if(DEBUGOut.prln(res);
184         resData = (ResourceDatacr.get(res.getClass().getName());
185         if(DEBUGOut.prln(resData);
186         if(! resData.isAutoLoading())
187           return false;
188       }
189     }
190 
191     return true;
192   // allAutoloaders
193 
194   /** Test resource discovery */
195   public void testDiscovery() throws Exception {
196 
197     CreoleRegister reg = Gate.getCreoleRegister();
198     if(DEBUG) {
199       Iterator iter = reg.values().iterator();
200       while(iter.hasNext()) Out.println(iter.next());
201     }
202 
203     ResourceData rd = (ResourceData)
204       reg.get("gate.creole.tokeniser.DefaultTokeniser");
205     assertNotNull("couldn't find unicode tok in register of resources", rd);
206     assertTrue(rd.getName().equals("ANNIE Unicode Tokeniser"));
207 
208     String docFormatName = "gate.corpora.XmlDocumentFormat";
209     ResourceData xmlDocFormatRD = (ResourceDatareg.get(docFormatName);
210     assertTrue(xmlDocFormatRD.getName().equals("Sheffield XML Document Format"));
211     assertTrue(xmlDocFormatRD.isAutoLoading());
212     
213     rd = reg.get("testpkg.TestPR1");
214     assertTrue(rd.getJarFileName().equals("TestResources.jar"));
215   // testDiscovery()
216 
217   /** Test resource metadata */
218   public void testMetadata() throws Exception {
219 
220     // get some res data from the register
221     ResourceData pr1rd = (ResourceDatareg.get("testpkg.TestPR1");
222     ResourceData pr2rd = (ResourceDatareg.get("testpkg.TestPR2");
223     assertTrue(pr1rd != null & pr2rd != null);
224     assertTrue(pr2rd.getName().equals("Sheffield Test PR 2"));
225 
226     // checks values of parameters of param0 in test pr 1
227     assertTrue(pr1rd.getClassName().equals("testpkg.TestPR1"));
228     Iterator iter = pr1rd.getParameterList().getRuntimeParameters().iterator();
229     Iterator iter2 = null;
230     Parameter param = null;
231     while(iter.hasNext()) {
232       iter2 = ((Listiter.next()).iterator();
233       while(iter2.hasNext()) {
234         param = (Parameteriter2.next();
235         if(param.typeName.equals("param0"))
236           break;
237       }
238       if(param.typeName.equals("param0"))
239         break;
240     }
241 
242     assertTrue("param0 was null", param != null);
243     assertTrue(param.typeName.equals("java.lang.String"));
244     assertTrue(param.optional);
245     assertTrue(! param.runtime);
246     assertTrue(param.comment == null);
247     assertTrue(param.name.equals("thing"));
248 
249     reg.clear();
250   // testMetadata()
251 
252   /** Test TOOLS and PRIVATE attributes */
253   public void testToolsAndPrivate() throws Exception {
254     ResourceData pr3rd = (ResourceDatareg.get("testpkg.PrintOutTokens");
255     assertTrue("couldn't get PR3", pr3rd != null);
256     assertTrue("PR3 not a tool", pr3rd.isTool());
257     if(DEBUGOut.prln(pr3rd.getFeatures());
258 
259     String docFormatName = "gate.corpora.XmlDocumentFormat";
260     ResourceData xmlDocFormatRD = (ResourceDatareg.get(docFormatName);
261     assertTrue("Xml doc format not PRIVATE", xmlDocFormatRD.isPrivate());
262     if(DEBUGOut.prln(xmlDocFormatRD.getFeatures());
263     
264     // this used to test the number of public and private LR
265     // instances known to the creole register, but this is no
266     // longer reliable as extras may (will) be defined by
267     // @CreoleResource annotations.
268 
269   // testToolsAndPrivate()
270 
271   /** Test resource loading */
272   public void testLoading() throws Exception {
273 
274     // get some res data from the register
275     assertTrue(
276       "wrong number of resources in the register: " + reg.size(),
277       reg.size() == 15
278     );
279     ResourceData pr1rd = (ResourceDatareg.get("testpkg.TestPR1");
280     ResourceData pr2rd = (ResourceDatareg.get("testpkg.TestPR2");
281     assertTrue("couldn't find PR1/PR2 res data", pr1rd != null && pr2rd != null);
282     assertTrue("wrong name on PR1", pr1rd.getName().equals("Sheffield Test PR 1"));
283 
284     // instantiation
285     ProcessingResource pr1 = (ProcessingResource)
286       Factory.createResource("testpkg.TestPR1", Factory.newFeatureMap());
287     ProcessingResource pr2 = (ProcessingResource)
288       Factory.createResource("testpkg.TestPR2", Factory.newFeatureMap());
289 
290     // run the beasts
291     FeatureMap pr1features = pr1.getFeatures();
292     FeatureMap pr2features = pr2.getFeatures();
293     assertNotNull("PR1 features are null", pr1features);
294     assertTrue(
295       "PR2 got wrong features: " + pr2features,
296       pr2features != null || pr2features.size() != 1
297     );
298     pr1.execute();
299     pr2.execute();
300     assertTrue(
301       "PR1 feature not present",
302       pr1.getFeatures().get("I").equals("have been run, thankyou")
303     );
304     assertTrue(
305       "PR2 feature not present",
306       pr2.getFeatures().get("I").equals("am in a bad mood")
307     );
308 
309     reg.clear();
310   // testLoading()
311 
312   /** Test resource indexing by class */
313   public void testClassIndex() throws Exception {
314 
315     ResourceData docRd = (ResourceDatareg.get("gate.corpora.DocumentImpl");
316     assertNotNull("couldn't find document res data", docRd);
317     assertTrue(
318       "doc res data has wrong class name",
319       docRd.getClassName().equals("gate.corpora.DocumentImpl")
320     );
321     assertTrue(
322       "doc res data has wrong interface name",
323       docRd.getInterfaceName().equals("gate.Document")
324     );
325 
326     Class docClass = docRd.getResourceClass();
327     assertNotNull("couldn't get doc class", docClass);
328     LanguageResource docRes = (LanguageResourcedocClass.newInstance();
329     assertTrue(
330       "instance of doc is wrong type",
331       docRes instanceof LanguageResource &&
332       docRes instanceof gate.Document
333     );
334 
335     reg.clear();
336   // testClassIndex()
337 
338   /** Test type lists */
339   public void testTypeLists() throws Exception {
340     Set vrs = reg.getVrTypes();
341     Set prs = reg.getPrTypes();
342     Set lrs = reg.getLrTypes();
343 
344     assertTrue("wrong number vrs in reg: " + vrs.size(), vrs.size() == 7);
345     assertTrue("wrong number prs in reg: " + prs.size(), prs.size() == 5);
346     assertTrue("wrong number lrs in reg: " + lrs.size(), lrs.size() == 3);
347   // testTypeLists()
348 
349   /** Test comments on resources */
350   public void testComments() throws Exception {
351 
352     ResourceData docRd = (ResourceDatareg.get("gate.corpora.DocumentImpl");
353     assertNotNull("testComments: couldn't find document res data", docRd);
354     String comment = docRd.getComment();
355     assertTrue(
356       "testComments: incorrect or missing COMMENT on document",
357       comment != null && comment.equals("GATE document")
358     );
359   // testComments()
360 
361   /** Test parameter defaults */
362   public void testParameterDefaults1() throws Exception {
363 
364     ResourceData docRd = (ResourceDatareg.get("gate.corpora.DocumentImpl");
365     assertNotNull("Couldn: couldn't find document res data", docRd);
366     if(DEBUGOut.prln(docRd.getParameterList().getInitimeParameters());
367     ParameterList paramList = docRd.getParameterList();
368     if(DEBUGOut.prln(docRd);
369 
370     // runtime params - none for a document
371     Iterator iter = paramList.getRuntimeParameters().iterator();
372     assertTrue("Document has runtime params: " + paramList, ! iter.hasNext());
373 
374     // init time params
375     Parameter param = null;
376     iter = paramList.getInitimeParameters().iterator();
377     int paramDisjNumber = -1;
378     while(iter.hasNext()) {
379       List paramDisj = (Listiter.next();
380       Iterator iter2 = paramDisj.iterator();
381       paramDisjNumber++;
382 
383       for(int i=0; iter2.hasNext(); i++) {
384         param = (Parameteriter2.next();
385 
386         switch(paramDisjNumber) {
387           case 0:
388             assertTrue(
389               "Doc param 0 wrong type: " + param.getTypeName(),
390               param.getTypeName().equals("java.lang.String")
391             );
392             assertTrue(
393               "Doc param 0 wrong name: " + param.getName(),
394               param.getName().equals("sourceUrlName")
395             );
396             Object defaultValue = param.calculateDefaultValue();
397             assertTrue(
398               "Doc param 0 default should be null but was: " + defaultValue,
399               defaultValue == null
400             );
401             break;
402           case 1:
403             assertTrue(
404               "Doc param 1 wrong name: " + param.getName(),
405               param.getName().equals(Document.DOCUMENT_ENCODING_PARAMETER_NAME)
406             );
407             break;
408           case 2:
409             assertTrue(
410               "Doc param 2 wrong name: " + param.getName(),
411               param.getName().equals(Document.DOCUMENT_START_OFFSET_PARAMETER_NAME)
412             );
413             break;
414           case 3:
415             assertTrue(
416               "Doc param 3 wrong name: " + param.getName(),
417               param.getName().equals(Document.DOCUMENT_END_OFFSET_PARAMETER_NAME)
418             );
419             break;
420           default:
421             //fail("Doc has more than 4 params; 5th is: " + param);
422             // don't fail if document has more than 4 params - it now pulls in
423             // extra ones from the @CreoleParameter annotations
424         // switch
425       }
426     }
427 
428   // testParameterDefaults1()
429 
430   /** Test parameter defaults (2) */
431   public void testParameterDefaults2() throws Exception {
432 
433     ResourceData rd = (ResourceDatareg.get("testpkg.PrintOutTokens");
434     assertNotNull("Couldn't find testpkg.POT res data", rd);
435 
436     // create a document, so that the parameter default will pick it up
437     Factory.newDocument(Gate.getUrl("tests/doc0.html"));
438 
439     ParameterList paramList = rd.getParameterList();
440     if(DEBUGOut.prln(rd);
441 
442     // init time params - none for this one
443     Iterator iter = paramList.getInitimeParameters().iterator();
444     assertTrue("POT has initime params: " + paramList, ! iter.hasNext());
445 
446     // runtime params
447     Parameter param = null;
448     iter = paramList.getRuntimeParameters().iterator();
449     int paramDisjNumber = -1;
450     while(iter.hasNext()) {
451       List paramDisj = (Listiter.next();
452       Iterator iter2 = paramDisj.iterator();
453       paramDisjNumber++;
454 
455       for(int i=0; iter2.hasNext(); i++) {
456         param = (Parameteriter2.next();
457 
458         switch(paramDisjNumber) {
459           case 0:
460             assertTrue(
461               "POT param 0 wrong type: " + param.getTypeName(),
462               param.getTypeName().equals("gate.corpora.DocumentImpl")
463             );
464             assertTrue(
465               "POT param 0 wrong name: " + param.getName(),
466               param.getName().equals("document")
467             );
468             Object defaultValue = param.calculateDefaultValue();
469             assertTrue(
470               "POT param 0 default should be Document but is " +
471               defaultValue.getClass().getName(),
472               defaultValue instanceof Document
473             );
474             break;
475           default:
476             fail("POT has more than 1 param; 2nd is: " + param);
477         // switch
478       }
479     }
480 
481   // testParameterDefaults2()
482 
483   /** Test param as lists*/
484   public void testParamAsLists() throws Exception{
485     ResourceData rd = (ResourceDatareg.get("testpkg.TestPR3");
486     assertNotNull("Couldn: couldn't find testPR3 res data", rd);
487 
488     ParameterList paramList = rd.getParameterList();
489     // runtime params - none for a document
490     List runTime = paramList.getRuntimeParameters();
491     assertTrue("PR3 should have 4 runtime params: " + paramList, runTime.size()==4);
492   }// End testParamAsLists();
493 
494   /** Test parameters */
495   public void testParameters() throws Exception {
496 
497     ResourceData docRd = (ResourceDatareg.get("gate.corpora.DocumentImpl");
498     assertNotNull("Couldn: couldn't find document res data", docRd);
499 
500     ParameterList paramList = docRd.getParameterList();
501     if(DEBUGOut.prln(docRd);
502 
503     // runtime params - none for a document
504     Iterator iter = paramList.getRuntimeParameters().iterator();
505     assertTrue("Document has runtime params: " + paramList, ! iter.hasNext());
506 
507     // init time params
508     Parameter param = null;
509     List initimeParams = paramList.getInitimeParameters();
510     // only check the four parameters we can control in tests/creole.xml
511     // there are more parameters after the fourth, but these come from
512     // @CreoleParameter annotations so we can't reliably control for them
513     // in this test
514     for(int paramDisjNumber = 0; paramDisjNumber < 4; paramDisjNumber++) {
515       List paramDisj = (List)initimeParams.get(paramDisjNumber);
516       Iterator iter2 = paramDisj.iterator();
517 
518       int paramDisjLen = paramDisj.size();
519       assertTrue(
520         "param disj wrong length: " + paramDisjLen,
521         paramDisjLen == 1
522       );
523 
524       for(int i=0; iter2.hasNext(); i++) {
525         param = (Parameteriter2.next();
526 
527         switch(paramDisjNumber) {
528           case 0:
529             assertTrue(
530               "Doc param 0 wrong type: " + param.getTypeName(),
531               param.getTypeName().equals("java.lang.String")
532             );
533             assertTrue(
534               "Doc param 0 wrong name: " + param.getName(),
535               param.getName().equals("sourceUrlName")
536             );
537             Object defaultValue = param.calculateDefaultValue();
538             assertTrue(
539               "Doc param 0 default should be null but was: " + defaultValue,
540               defaultValue == null
541             );
542             break;
543           case 1:
544             assertTrue(
545               "Doc param 1 wrong name: " + param.getName(),
546               param.getName().equals(Document.DOCUMENT_ENCODING_PARAMETER_NAME)
547             );
548             break;
549           case 2:
550             assertTrue(
551               "Doc param 2 wrong name: " + param.getName(),
552               param.getName().equals(Document.DOCUMENT_START_OFFSET_PARAMETER_NAME)
553             );
554             defaultValue = param.getDefaultValue();
555             break;
556           case 3:
557             assertTrue(
558               "Doc param 3 wrong name: " + param.getName(),
559               param.getName().equals(Document.DOCUMENT_END_OFFSET_PARAMETER_NAME)
560             );
561             break;
562           default:
563             // can't be reached
564         // switch
565       }
566     }
567 
568   // testParameters()
569 
570   /** Test default run() on processing resources */
571   public void testDefaultRun() throws Exception {
572     ProcessingResource defaultPr = new AbstractProcessingResource() {
573     };
574     boolean gotExceptionAsExpected = false;
575     try {
576       defaultPr.execute();
577     catch(ExecutionException e) {
578       gotExceptionAsExpected = true;
579     }
580 
581     assertTrue("check should have thrown exception", gotExceptionAsExpected);
582   // testDefaultRun()
583 
584   /** Test arbitrary metadata elements on resources */
585   public void testArbitraryMetadata() throws Exception {
586 
587     ResourceData docRd = (ResourceDatareg.get("gate.corpora.DocumentImpl");
588     assertNotNull("testArbitraryMetadata: couldn't find doc res data", docRd);
589     FeatureMap features = docRd.getFeatures();
590     String comment = (Stringfeatures.get("FUNKY-METADATA-THAING");
591     assertTrue(
592       "testArbitraryMetadata: incorrect FUNKY-METADATA-THAING on document",
593       comment != null && comment.equals("hubba hubba")
594     );
595   // testArbitraryMetadata()
596 
597   /** Test resource introspection */
598   public void testIntrospection() throws Exception {
599     // get the gate.Document resource and its class
600     ResourceData docRd = (ResourceDatareg.get("gate.corpora.DocumentImpl");
601     assertNotNull("couldn't find document res data (2)", docRd);
602     Class resClass = docRd.getResourceClass();
603 
604     // get the beaninfo and property descriptors for the resource
605     BeanInfo docBeanInfo = Introspector.getBeanInfo(resClass, Object.class);
606     PropertyDescriptor[] propDescrs = docBeanInfo.getPropertyDescriptors();
607 
608     // print all the properties in the reource's bean info;
609     // remember the setFeatures method
610     Method setFeaturesMethod = null;
611     for(int i = 0; i<propDescrs.length; i++) {
612       Method getMethodDescr = null;
613       Method setMethodDescr = null;
614       Class propClass = null;
615 
616       PropertyDescriptor propDescr = propDescrs[i];
617       propClass = propDescr.getPropertyType();
618       getMethodDescr = propDescr.getReadMethod();
619       setMethodDescr = propDescr.getWriteMethod();
620 
621       if(
622         setMethodDescr != null &&
623         setMethodDescr.getName().equals("setFeatures")
624       )
625         setFeaturesMethod = setMethodDescr;
626 
627       if(DEBUGprintProperty(propDescrs[i]);
628     }
629 
630     // try setting the features property
631     // invoke(Object obj, Object[] args)
632     LanguageResource res = (LanguageResourceresClass.newInstance();
633     FeatureMap feats = Factory.newFeatureMap();
634     feats.put("things are sunny in sunny countries""aren't they?");
635     Object[] args = new Object[1];
636     args[0= feats;
637     setFeaturesMethod.invoke(res, args);
638     assertTrue(
639       "features not added to resource properly",
640       res.getFeatures().get("things are sunny in sunny countries")
641         .equals("aren't they?")
642     );
643   // testIntrospection
644 
645   /** Test the Factory resource creation provisions */
646   public void testFactory() throws Exception {
647     FeatureMap params = Factory.newFeatureMap();
648     params.put("features", Factory.newFeatureMap());
649     params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html")
650     );
651     Resource res =
652       Factory.createResource("gate.corpora.DocumentImpl", params);
653   // testFactory
654 
655   /** Utility method to print out the values of a property descriptor
656     @see java.beans.PropertyDescriptor
657     */
658   public static void printProperty(PropertyDescriptor prop) {
659     Class propClass = prop.getPropertyType();
660     Method getMethodDescr = prop.getReadMethod();
661     Method setMethodDescr = prop.getWriteMethod();
662     Out.pr("prop dispname= " + prop.getDisplayName() "; ");
663     Out.pr("prop type name= " + propClass.getName() "; ");
664     if(getMethodDescr != null)
665       Out.pr("get meth name= " + getMethodDescr.getName() "; ");
666     if(setMethodDescr != null)
667       Out.pr("set meth name= " + setMethodDescr.getName() "; ");
668     Out.prln();
669   // printProperty
670 
671   /** Example of what bean info classes do.
672     * If this was a public class in gate.corpora it would be used
673     * by the beans Introspector to generation bean info for the
674     * gate.corpora.DocumentImpl class. It inherits from SimpleBeanInfo
675     * whose default behaviour is to return null for the various methods;
676     * this tells the Introspector to do its own investigations.
677     */
678   class DocumentImplBeanInfo extends SimpleBeanInfo {
679 
680     /** Override the SimpleBeanInfo behaviour and return a 0-length
681       * array of properties; this will be passed on by the Introspector,
682       * the effect being to block info on the properties of the bean.
683       */
684     public PropertyDescriptor[] getPropertyDescriptors() {
685       return new PropertyDescriptor[0];
686     // getPropertyDescriptors
687 
688   // DocumentImplBeanInfo
689 
690   /** Test suite routine for the test runner */
691   public static Test suite() {
692     return new TestSuite(TestCreole.class);
693   // suite
694 
695 // class TestCreole