1   /*
2    *  CreoleRegisterImpl.java
3    *
4    *  Copyright (c) 1998-2001, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Hamish Cunningham, 1/Sept/2000
12   *
13   *  $Id: CreoleRegisterImpl.java,v 1.52 2002/04/30 14:38:46 valyt Exp $
14   */
15  
16  package gate.creole;
17  
18  import java.util.*;
19  import java.net.*;
20  import java.io.*;
21  
22  import org.xml.sax.*;
23  import javax.xml.parsers.*;
24  import org.xml.sax.helpers.*;
25  
26  import gate.*;
27  import gate.util.*;
28  import gate.event.*;
29  
30  
31  /** This class implements the CREOLE register interface. DO NOT
32    * construct objects of this class unless your name is gate.Gate
33    * (in which case please go back to the source code repository and stop
34    * looking at other class's code).
35    * <P>
36    * The CREOLE register records the set of resources that are currently
37    * known to the system. Each member of the register is a
38    * {@link gate.creole.ResourceData} object, indexed by
39    * the class name of the resource.
40    * @see gate.CreoleRegister
41    */
42  public class CreoleRegisterImpl extends HashMap
43            implements CreoleRegister, CreoleListener
44  {
45    /** Debug flag */
46    protected static final boolean DEBUG = false;
47  
48    /** The set of CREOLE directories (URLs). */
49    protected Set directories;
50  
51    /** The parser for the CREOLE directory files */
52    protected transient SAXParser parser = null;
53  
54    /**
55     * Default constructor. Sets up directory files parser. <B>NOTE:</B>
56     * only Factory should call this method.
57     */
58    public CreoleRegisterImpl() throws GateException {
59  
60      // initialise the various maps
61      directories = new HashSet();
62      lrTypes = new HashSet();
63      prTypes = new HashSet();
64      vrTypes = new LinkedList();
65      toolTypes = new HashSet();
66  
67      // construct a SAX parser for parsing the CREOLE directory files
68      try {
69        // Get a parser factory.
70        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
71  
72        // Set up the factory to create the appropriate type of parser:
73        // non validating one
74        saxParserFactory.setValidating(false);
75        // non namespace aware one
76        saxParserFactory.setNamespaceAware(true);
77  
78        // create the parser
79        parser = saxParserFactory.newSAXParser();
80  
81      } catch (SAXException e) {
82        if(DEBUG) Out.println(e);
83        throw(new GateException(e));
84      } catch (ParserConfigurationException e) {
85        if(DEBUG) Out.println(e);
86        throw(new GateException(e));
87      }
88  
89    } // default constructor
90  
91    /** Add a CREOLE directory URL to the register and to the GATE classloader.
92      * The directory is <B>not</B> registered.
93      */
94    public void addDirectory(URL directoryUrl) {
95      directories.add(directoryUrl);
96    } // addDirectory
97  
98    /** Get the list of CREOLE directory URLs. */
99    public Set getDirectories() {
100     return Collections.unmodifiableSet(directories);
101   } // getDirectories
102 
103   /** Register all the CREOLE directories that we know of.
104     * The <CODE>creole.xml</CODE> files
105     * at the URLs are parsed, and <CODE>ResourceData</CODE> objects added
106     * to the register.
107     * URLs for resource JAR files are added to the GATE class loader.
108     */
109   public void registerDirectories() throws GateException {
110     Iterator iter = directories.iterator();
111 
112     while(iter.hasNext()) {
113       URL directoryUrl = (URL) iter.next();
114       registerDirectories(directoryUrl);
115     }
116   } // registerDirectories
117 
118   /** Register a single CREOLE directory. The <CODE>creole.xml</CODE>
119     * file at the URL is parsed, and <CODE>CreoleData</CODE> objects added
120     * to the register. If the directory URL has not yet been added it
121     * is now added.
122     * URLs for resource JAR files are added to the GATE class loader.
123     */
124   public void registerDirectories(URL directoryUrl) throws GateException {
125 
126     // directory URLs shouldn't include "creole.xml"
127     String urlName = directoryUrl.toExternalForm();
128     if(urlName.toLowerCase().endsWith("creole.xml")) {
129       throw new GateException(
130         "CREOLE directory URLs should point to the parent location of " +
131         "the creole.xml file, not the file itself; bad URL was: " + urlName
132       );
133     }
134 
135     // create a URL for the creole.xml file, based on the directory URL
136     URL directoryXmlFileUrl = directoryUrl;
137     String separator = "/";
138     if(urlName.endsWith(separator)) separator = "";
139     try {
140       directoryXmlFileUrl = new URL(urlName + separator + "creole.xml");
141     } catch(MalformedURLException e) {
142       throw(new GateException("bad creole.xml URL, based on " + urlName));
143     }
144 
145     // add the URL
146     //if already present do nothing
147     directories.add(directoryUrl);
148     // parse the directory file
149     try {
150       parseDirectory(directoryXmlFileUrl.openStream(), directoryUrl);
151     } catch(IOException e) {
152       //it failed: remove it
153       directories.remove(directoryUrl);
154       throw(new GateException("couldn't open creole.xml: " + e.toString()));
155     }
156   } // registerDirectories(URL)
157 
158   /** Parse a directory file (represented as an open stream), adding
159     * resource data objects to the CREOLE register as they occur.
160     * If the resource is from a URL then that location is passed (otherwise
161     * null).
162     */
163   protected void parseDirectory(InputStream directoryStream, URL directoryUrl)
164   throws GateException
165   {
166     // create a handler for the directory file and parse it;
167     // this will create ResourceData entries in the register
168     try {
169       DefaultHandler handler = new CreoleXmlHandler(this, directoryUrl);
170       parser.parse(directoryStream, handler);
171       if(DEBUG) {
172         Out.prln(
173           "done parsing " +
174           ((directoryUrl == null) ? "null" : directoryUrl.toString())
175         );
176       }
177     } catch (IOException e) {
178       throw(new GateException(e));
179     } catch (SAXException e) {
180       if(DEBUG) Out.println(e.toString());
181       throw(new GateException(e));
182     }
183 
184   } // parseDirectory
185 
186   /** Register resources that are built in to the GATE distribution.
187     * These resources are described by the <TT>creole.xml</TT> file in
188     * <TT>resources/creole</TT>.
189     */
190   public void registerBuiltins() throws GateException {
191 
192     try {
193       parseDirectory(
194         new URL("gate:/creole/creole.xml").openStream(),
195         new URL("gate:/creole/")
196       );
197     } catch(IOException e) {
198       if (DEBUG) Out.println(e);
199       throw(new GateException(e));
200     }
201   } // registerBuiltins()
202 
203   /** This is a utility method for creating CREOLE directory files
204     * (typically called <CODE>creole.xml</CODE>) from a list of Jar
205     * files that contain resources. The method concatenates the
206     * <CODE>resource.xml</CODE> files that the Jars contain.
207     * <P>
208     * If Java allowed class methods in interfaces this would be static.
209     */
210   public File createCreoleDirectoryFile(File directoryFile, Set jarFileNames)
211   {
212     ////////////////////
213     // dump xml header and comment header and <CREOLE-DIRECTORY> into dirfile
214     // for each jar file pick out resource.xml
215     // strip xml header
216     // dump into dirfile
217     // put </CREOLE-DIRECTORY> into dirfile
218     throw new LazyProgrammerException();
219   } // createCreoleDirectoryFile
220 
221   /** Overide HashMap's put method to maintain a list of all the
222     * types of LR in the register, and a list of tool types. The key is
223     * the resource type, the value its data.
224     */
225   public Object put(Object key, Object value) {
226     ResourceData rd = (ResourceData) value;
227 
228     // get the resource implementation class
229     Class resClass = null;
230     try {
231       resClass = rd.getResourceClass();
232     } catch(ClassNotFoundException e) {
233       throw new GateRuntimeException(
234         "Couldn't get resource class from the resource data:" + e
235       );
236     }
237 
238     // add class names to the type lists
239     if(LanguageResource.class.isAssignableFrom(resClass)) {
240       if(DEBUG) Out.prln("LR: " + resClass);
241       if(lrTypes == null) lrTypes = new HashSet(); // for deserialisation
242       lrTypes.add(rd.getClassName());
243     } else if(ProcessingResource.class.isAssignableFrom(resClass)) {
244       if(DEBUG) {
245         Out.prln("PR: " + resClass);
246         //Out.prln("prTypes: " + prTypes);
247         //Out.prln("rd.getClassName(): " + rd.getClassName());
248       }
249       if(prTypes == null) prTypes = new HashSet(); // for deserialisation
250       prTypes.add(rd.getClassName());
251     } else if(VisualResource.class.isAssignableFrom(resClass)) {
252       if(DEBUG) Out.prln("VR: " + resClass);
253       if(vrTypes == null) vrTypes = new LinkedList(); // for deserialisation
254       //we have to simulate Set behaviour as this is a list
255       if(!vrTypes.contains(rd.getClassName())) vrTypes.add(rd.getClassName());
256     }else if(Controller.class.isAssignableFrom(resClass)) {
257       if(DEBUG) Out.prln("Controller: " + resClass);
258       if(controllerTypes == null) controllerTypes = new HashSet(); // for deserialisation
259       controllerTypes.add(rd.getClassName());
260     }
261 
262     // maintain tool types list
263     if(rd.isTool()) {
264       if(toolTypes == null) toolTypes = new HashSet(); // for deserialisation
265       toolTypes.add(rd.getClassName());
266     }
267 
268     return super.put(key, value);
269   } // put(key, value)
270 
271   /** Overide HashMap's delete method to update the lists of types
272     * in the register.
273     */
274   public Object remove(Object key) {
275     ResourceData rd = (ResourceData) get(key);
276     if(rd == null) return null;
277 
278     if(DEBUG) {
279       Out.prln(key);
280       Out.prln(rd);
281     }
282     if(LanguageResource.class.isAssignableFrom(rd.getClass()))
283       lrTypes.remove(rd.getClassName());
284     else if(ProcessingResource.class.isAssignableFrom(rd.getClass()))
285       prTypes.remove(rd.getClassName());
286     else if(VisualResource.class.isAssignableFrom(rd.getClass()))
287       vrTypes.remove(rd.getClassName());
288 
289     // maintain tool types list
290     if(rd.isTool())
291       toolTypes.remove(rd.getClassName());
292 
293     return super.remove(key);
294   } // remove(Object)
295 
296   /** Overide HashMap's clear to update the list of LR types in the register,
297     * and remove all resources and forgets all directories.
298     */
299   public void clear() {
300     lrTypes.clear();
301     prTypes.clear();
302     vrTypes.clear();
303     toolTypes.clear();
304     directories.clear();
305     super.clear();
306   } // clear()
307 
308   /** Get the list of types of LR in the register. */
309   public Set getLrTypes() { return Collections.unmodifiableSet(lrTypes);}
310 
311   /** Get the list of types of PR in the register. */
312   public Set getPrTypes() { return Collections.unmodifiableSet(prTypes);}
313 
314   /** Get the list of types of VR in the register. */
315   public Set getVrTypes() { return Collections.unmodifiableSet(new HashSet(vrTypes));}
316 
317   /** Get the list of types of VR in the register. */
318   public Set getControllerTypes() {
319     return Collections.unmodifiableSet(controllerTypes);
320   }
321 
322   /** Get the list of types of TOOL respurces in the register. */
323   public Set getToolTypes() { return Collections.unmodifiableSet(toolTypes);}
324 
325   /** Get a list of all instantiations of LR in the register. */
326   public List getLrInstances() {
327     Set lrTypeSet = getLrTypes();
328     List instances = new ArrayList();
329 
330     Iterator iter = lrTypeSet.iterator();
331     while(iter.hasNext()) {
332       String type = (String) iter.next();
333       instances.addAll(getLrInstances(type));
334     }// End while
335     return Collections.unmodifiableList(instances);
336   } // getLrInstances()
337 
338   /** Get a list of all instantiations of PR in the register. */
339   public List getPrInstances() {
340     Set prTypeSet = getPrTypes();
341     List instances = new ArrayList();
342 
343     Iterator iter = prTypeSet.iterator();
344     while(iter.hasNext()) {
345       String type = (String) iter.next();
346       instances.addAll(getPrInstances(type));
347     }// End while
348 
349     return Collections.unmodifiableList(instances);
350   } // getPrInstances()
351 
352   /** Get a list of all instantiations of VR in the register. */
353   public List getVrInstances() {
354     Set vrTypeSet = getVrTypes();
355     List instances = new ArrayList();
356 
357     Iterator iter = vrTypeSet.iterator();
358     while(iter.hasNext()) {
359       String type = (String) iter.next();
360       instances.addAll(getVrInstances(type));
361     }// End while
362 
363     return Collections.unmodifiableList(instances);
364   } // getVrInstances()
365 
366   /** Get a list of instantiations of a type of LR in the register. */
367   public List getLrInstances(String resourceTypeName) {
368     ResourceData resData = (ResourceData) get(resourceTypeName);
369     if(resData == null)
370       return Collections.unmodifiableList(new ArrayList());
371 
372     return Collections.unmodifiableList(resData.getInstantiations());
373   } // getLrInstances
374 
375   /** Get a list of instantiations of a type of PR in the register. */
376   public List getPrInstances(String resourceTypeName) {
377     ResourceData resData = (ResourceData) get(resourceTypeName);
378     if(resData == null)
379       return Collections.unmodifiableList(new ArrayList());
380 
381     return Collections.unmodifiableList(resData.getInstantiations());
382   } // getPrInstances
383 
384   /** Get a list of instantiations of a type of VR in the register. */
385   public List getVrInstances(String resourceTypeName) {
386     ResourceData resData = (ResourceData) get(resourceTypeName);
387     if(resData == null)
388       return Collections.unmodifiableList(new ArrayList());
389 
390     return Collections.unmodifiableList(resData.getInstantiations());
391   } // getVrInstances
392 
393   /** Get a list of all non-private instantiations of LR in the register. */
394   public List getPublicLrInstances() {
395     return Collections.unmodifiableList(getPublics(getLrInstances()));
396   }// getPublicLrInstances()
397 
398   /** Get a list of all non-private instantiations of PR in the register. */
399   public List getPublicPrInstances() {
400     return Collections.unmodifiableList(getPublics(getPrInstances()));
401   }// getPublicPrInstances()
402 
403   /** Get a list of all non-private instantiations of VR in the register. */
404   public List getPublicVrInstances() {
405     return Collections.unmodifiableList(getPublics(getVrInstances()));
406   }//getPublicVrInstances()
407 
408   /** Get a list of all non-private types of LR in the register. */
409   public List getPublicLrTypes() {
410     return Collections.unmodifiableList(getPublicTypes(getLrTypes()));
411   }//getPublicLrTypes()
412 
413   /** Get a list of all non-private types of PR in the register. */
414   public List getPublicPrTypes() {
415     return Collections.unmodifiableList(getPublicTypes(getPrTypes()));
416   }//getPublicPrTypes()
417 
418   /** Get a list of all non-private types of VR in the register. */
419   public List getPublicVrTypes() {
420     return Collections.unmodifiableList(getPublicTypes(getVrTypes()));
421   }//getPublicVrTypes()
422 
423   /** Get a list of all non-private types of controller in the register. */
424   public List getPublicControllerTypes() {
425     return Collections.unmodifiableList(getPublicTypes(getControllerTypes()));
426   }//getPublicPrTypes()
427 
428 
429   /**
430    * Gets all the instantiations of a given type and all its derivate types;
431    * It doesn't return instances that have the hidden attribute set to "true"
432    */
433   public List getAllInstances(String type) throws GateException{
434     Iterator typesIter = keySet().iterator();
435     List res = new ArrayList();
436     Class targetClass;
437     try{
438       targetClass = Gate.getClassLoader().loadClass(type);
439     }catch(ClassNotFoundException cnfe){
440       throw new GateException("Invalid type " + type);
441     }
442     while(typesIter.hasNext()){
443       String aType = (String)typesIter.next();
444       Class aClass;
445       try{
446         aClass = Gate.getClassLoader().loadClass(aType);
447         if(targetClass.isAssignableFrom(aClass)){
448           //filter out hidden instances
449           Iterator newInstancesIter = ((ResourceData)get(aType)).
450                                       getInstantiations().iterator();
451           while(newInstancesIter.hasNext()){
452             Resource instance = (Resource)newInstancesIter.next();
453             if(!Gate.getHiddenAttribute(instance.getFeatures())){
454               res.add(instance);
455             }
456           }
457         }
458       }catch(ClassNotFoundException cnfe){
459         throw new LuckyException(
460           "A type registered in the creole register does not exist in the VM!");
461       }
462 
463     }//while(typesIter.hasNext())
464 
465     return res;
466   }
467 
468   /**
469    * Returns a list of strings representing class names for large VRs valid
470    * for a given type of language/processing resource.
471    * The default VR will be the first in the returned list.
472    * @param resoureClassName the name of the resource that has large viewers. If
473    * resourceClassName is <b>null</b> then an empty list will be returned.
474    * @return a list with Strings representing the large VRs for the
475    * resourceClassName
476    */
477   public List getLargeVRsForResource(String resourceClassName){
478     return getVRsForResource(resourceClassName, ResourceData.LARGE_GUI);
479   }// getLargeVRsForResource()
480 
481   /**
482    * Returns a list of strings representing class names for small VRs valid
483    * for a given type of language/processing resource
484    * The default VR will be the first in the returned list.
485    * @param resoureClassName the name of the resource that has large viewers. If
486    * resourceClassName is <b>null</b> then an empty list will be returned.
487    * @return a list with Strings representing the large VRs for the
488    * resourceClassName
489    */
490   public List getSmallVRsForResource(String resourceClassName){
491     return getVRsForResource(resourceClassName, ResourceData.SMALL_GUI);
492   }// getSmallVRsForResource
493 
494   /**
495    * Returns a list of strings representing class names for guiType VRs valid
496    * for a given type of language/processing resource
497    * The default VR will be the first in the returned list.
498    * @param resoureClassName the name of the resource that has large viewers. If
499    * resourceClassName is <b>null</b> then an empty list will be returned.
500    * @param guiType can be ResourceData's LARGE_GUI or SMALL_GUI
501    * @return a list with Strings representing the large VRs for the
502    * resourceClassName
503    */
504   private List getVRsForResource(String resourceClassName, int guiType){
505     // If resurceClassName is null return a simply list
506     if (resourceClassName == null)
507       return Collections.unmodifiableList(new ArrayList());
508     // create a Class object for the resource
509     Class resourceClass = null;
510     GateClassLoader classLoader = Gate.getClassLoader();
511     try{
512       resourceClass = classLoader.loadClass(resourceClassName);
513     } catch (ClassNotFoundException ex){
514       throw new GateRuntimeException(
515         "Couldn't get resource class from the resource name:" + ex
516       );
517     }// End try
518     LinkedList responseList = new LinkedList();
519     String defaultVR = null;
520     // Take all VRs and for each large one, test if
521     // resourceClassName is asignable form VR's RESOURCE_DISPLAYED
522     Iterator vrIterator = vrTypes.iterator();
523     while (vrIterator.hasNext()){
524       String vrClassName = (String) vrIterator.next();
525       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
526       if (vrResourceData == null)
527         throw new GateRuntimeException(
528           "Couldn't get resource data for VR called " + vrClassName
529         );
530       if (vrResourceData.getGuiType() == guiType){
531         String resourceDisplayed = vrResourceData.getResourceDisplayed();
532         if (resourceDisplayed != null){
533           Class resourceDisplayedClass = null;
534           try{
535             resourceDisplayedClass = classLoader.loadClass(resourceDisplayed);
536           } catch (ClassNotFoundException ex){
537               throw new GateRuntimeException(
538                 "Couldn't get resource class from the resource name :" +
539                 resourceDisplayed + " " +ex );
540           }// End try
541           if (resourceDisplayedClass.isAssignableFrom(resourceClass)){
542             responseList.add(vrClassName);
543             if (vrResourceData.isMainView()){
544               defaultVR = vrClassName;
545             }// End if
546           }// End if
547         }// End if
548       }// End if
549     }// End while
550     if (defaultVR != null){
551       responseList.remove(defaultVR);
552       responseList.addFirst(defaultVR);
553     }// End if
554     return Collections.unmodifiableList(responseList);
555   }// getVRsForResource()
556 
557   /**
558    * Returns a list of strings representing class names for annotation VRs
559    * that are able to display/edit all types of annotations.
560    * The default VR will be the first in the returned list.
561    * @return a list with all VRs that can display all annotation types
562    */
563   public List getAnnotationVRs(){
564     LinkedList responseList = new LinkedList();
565     String defaultVR = null;
566     Iterator vrIterator = vrTypes.iterator();
567     while (vrIterator.hasNext()){
568       String vrClassName = (String) vrIterator.next();
569       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
570       if (vrResourceData == null)
571         throw new GateRuntimeException(
572           "Couldn't get resource data for VR called " + vrClassName
573         );
574       Class vrResourceClass = null;
575       try{
576         vrResourceClass = vrResourceData.getResourceClass();
577       } catch(ClassNotFoundException ex){
578         throw new GateRuntimeException(
579           "Couldn't create a class object for VR called " + vrClassName
580         );
581       }// End try
582       // Test if VR can display all types of annotations
583       if ( vrResourceData.getGuiType() == ResourceData.NULL_GUI &&
584            vrResourceData.getAnnotationTypeDisplayed() == null &&
585            vrResourceData.getResourceDisplayed() == null &&
586            gate.creole.AnnotationVisualResource.class.
587                                           isAssignableFrom(vrResourceClass)){
588 
589           responseList.add(vrClassName);
590           if (vrResourceData.isMainView())
591               defaultVR = vrClassName;
592       }// End if
593     }// End while
594     if (defaultVR != null){
595       responseList.remove(defaultVR);
596       responseList.addFirst(defaultVR);
597     }// End if
598     return Collections.unmodifiableList(responseList);
599   }// getAnnotationVRs()
600 
601   /**
602    * Returns a list of strings representing class names for annotation VRs
603    * that are able to display/edit a given annotation type
604    * The default VR will be the first in the returned list.
605    */
606   public List getAnnotationVRs(String annotationType){
607     if (annotationType == null)
608       return Collections.unmodifiableList(new ArrayList());
609     LinkedList responseList = new LinkedList();
610     String defaultVR = null;
611     Iterator vrIterator = vrTypes.iterator();
612     while (vrIterator.hasNext()){
613       String vrClassName = (String) vrIterator.next();
614       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
615       if (vrResourceData == null)
616         throw new GateRuntimeException(
617           "Couldn't get resource data for VR called " + vrClassName
618         );
619       Class vrResourceClass = null;
620       try{
621         vrResourceClass = vrResourceData.getResourceClass();
622       } catch(ClassNotFoundException ex){
623         throw new GateRuntimeException(
624           "Couldn't create a class object for VR called " + vrClassName
625         );
626       }// End try
627       // Test if VR can display all types of annotations
628       if ( vrResourceData.getGuiType() == ResourceData.NULL_GUI &&
629            vrResourceData.getAnnotationTypeDisplayed() != null &&
630            gate.creole.AnnotationVisualResource.class.
631                                           isAssignableFrom(vrResourceClass)){
632 
633           String annotationTypeDisplayed =
634                                   vrResourceData.getAnnotationTypeDisplayed();
635           if (annotationTypeDisplayed.equals(annotationType)){
636             responseList.add(vrClassName);
637             if (vrResourceData.isMainView())
638               defaultVR = vrClassName;
639           }// End if
640       }// End if
641     }// End while
642     if (defaultVR != null){
643       responseList.remove(defaultVR);
644       responseList.addFirst(defaultVR);
645     }// End if
646     return Collections.unmodifiableList(responseList);
647   }//getAnnotationVRs()
648 
649    /**
650     * Renames an existing resource.
651     */
652    public void setResourceName(Resource res, String newName){
653     String oldName = res.getName();
654     res.setName(newName);
655     fireResourceRenamed(res, oldName, newName);
656    }
657 
658 
659   /**
660    * Returns a list of strings representing annotations types for which
661    * there are custom viewers/editor registered.
662    */
663   public List getVREnabledAnnotationTypes(){
664     LinkedList responseList = new LinkedList();
665     Iterator vrIterator = vrTypes.iterator();
666     while (vrIterator.hasNext()){
667       String vrClassName = (String) vrIterator.next();
668       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
669       if (vrResourceData == null)
670         throw new GateRuntimeException(
671           "Couldn't get resource data for VR called " + vrClassName
672         );
673       // Test if VR can display all types of annotations
674       if ( vrResourceData.getGuiType() == ResourceData.NULL_GUI &&
675            vrResourceData.getAnnotationTypeDisplayed() != null ){
676 
677           String annotationTypeDisplayed =
678                                   vrResourceData.getAnnotationTypeDisplayed();
679           responseList.add(annotationTypeDisplayed);
680       }// End if
681     }// End while
682     return Collections.unmodifiableList(responseList);
683   }// getVREnabledAnnotationTypes()
684 
685 
686 
687   /** Get a list of all non-private instantiations. */
688   protected List getPublics(List instances) {
689     Iterator iter = instances.iterator();
690     List publics = new ArrayList();
691 
692     // for each instance, if resource data specifies it isn't private,
693     // add to the publics list
694     while(iter.hasNext()) {
695       Resource res = (Resource) iter.next();
696       ResourceData rd = (ResourceData) get(res.getClass().getName());
697       if(! rd.isPrivate()) publics.add(res);
698     }
699 
700     return Collections.unmodifiableList(publics);
701   } // getPublics
702 
703   /** Gets a list of all non private types from alist of types*/
704   protected List getPublicTypes(Collection types){
705     Iterator iter = types.iterator();
706     List publics = new ArrayList();
707     while(iter.hasNext()){
708       String oneType = (String)iter.next();
709       ResourceData rData = (ResourceData)get(oneType);
710       if(rData != null && !rData.isPrivate()) publics.add(oneType);
711     }
712     return Collections.unmodifiableList(publics);
713   }//getPublicTypes
714 
715   public synchronized void removeCreoleListener(CreoleListener l) {
716     if (creoleListeners != null && creoleListeners.contains(l)) {
717       Vector v = (Vector) creoleListeners.clone();
718       v.removeElement(l);
719       creoleListeners = v;
720     }
721   }
722 
723   public synchronized void addCreoleListener(CreoleListener l) {
724     Vector v = creoleListeners == null ? new Vector(2) : (Vector) creoleListeners.clone();
725     if (!v.contains(l)) {
726       v.addElement(l);
727       creoleListeners = v;
728     }
729   } // getPublicTypes
730 
731   /**
732    * Removes a {@link gate.event.CreoleListener} previously registered with this
733    * CreoleRegister. {@see #addCreoleListener()}
734    */
735 
736   /**
737    * Registers a {@link gate.event.CreoleListener}with this CreoleRegister.
738    * The register will fire events every time a resource is added to or removed
739    * from the system.
740    */// addCreoleListener
741 
742   /**
743    * Notifies all listeners that a new {@link gate.Resource} has been loaded
744    * into the system
745    */// fireResourceLoaded
746 
747   /**
748    * Notifies all listeners that a {@link gate.Resource} has been unloaded
749    * from the system
750    */// fireResourceUnloaded
751 
752   /** A list of the types of LR in the register. */
753   protected Set lrTypes;
754 
755   /** A list of the types of PR in the register. */
756   protected Set prTypes;
757 
758   /** A list of the types of VR in the register. */
759   protected List vrTypes;
760 
761   /** A list of the types of VR in the register. */
762   protected Set controllerTypes;
763 
764   /** A list of the types of TOOL in the register. */
765   protected Set toolTypes;
766 
767   private transient Vector creoleListeners;
768   protected void fireResourceLoaded(CreoleEvent e) {
769     if (creoleListeners != null) {
770       Vector listeners = creoleListeners;
771       int count = listeners.size();
772       for (int i = 0; i < count; i++) {
773         ((CreoleListener) listeners.elementAt(i)).resourceLoaded(e);
774       }
775     }
776   }
777 
778   protected void fireResourceUnloaded(CreoleEvent e) {
779     if (creoleListeners != null) {
780       Vector listeners = creoleListeners;
781       int count = listeners.size();
782       for (int i = 0; i < count; i++) {
783         ((CreoleListener) listeners.elementAt(i)).resourceUnloaded(e);
784       }
785     }
786   }
787 
788   protected void fireResourceRenamed(Resource res, String oldName,
789                                      String newName) {
790     if (creoleListeners != null) {
791       Vector listeners = creoleListeners;
792       int count = listeners.size();
793       for (int i = 0; i < count; i++) {
794         ((CreoleListener) listeners.elementAt(i)).resourceRenamed(res,
795                                                                   oldName,
796                                                                   newName);
797       }
798     }
799   }
800 
801   protected void fireDatastoreOpened(CreoleEvent e) {
802     if (creoleListeners != null) {
803       Vector listeners = creoleListeners;
804       int count = listeners.size();
805       for (int i = 0; i < count; i++) {
806         ((CreoleListener) listeners.elementAt(i)).datastoreOpened(e);
807       }
808     }
809   }
810   protected void fireDatastoreCreated(CreoleEvent e) {
811     if (creoleListeners != null) {
812       Vector listeners = creoleListeners;
813       int count = listeners.size();
814       for (int i = 0; i < count; i++) {
815         ((CreoleListener) listeners.elementAt(i)).datastoreCreated(e);
816       }
817     }
818   }
819 
820   protected void fireDatastoreClosed(CreoleEvent e) {
821     if (creoleListeners != null) {
822       Vector listeners = creoleListeners;
823       int count = listeners.size();
824       for (int i = 0; i < count; i++) {
825         ((CreoleListener) listeners.elementAt(i)).datastoreClosed(e);
826       }
827     }
828   }
829 
830   public void resourceLoaded(CreoleEvent e) {
831     fireResourceLoaded(e);
832   }
833 
834   public void resourceUnloaded(CreoleEvent e) {
835     fireResourceUnloaded(e);
836   }
837 
838   public void resourceRenamed(Resource resource, String oldName,
839                               String newName){
840     fireResourceRenamed(resource, oldName, newName);
841   }
842 
843   public void datastoreOpened(CreoleEvent e) {
844     fireDatastoreOpened(e);
845   }
846 
847   public void datastoreCreated(CreoleEvent e) {
848     fireDatastoreCreated(e);
849   }
850 
851   public void datastoreClosed(CreoleEvent e) {
852     fireDatastoreClosed(e);
853   }
854 
855   /**The lists of listeners registered with this CreoleRegister*/
856 } // class CreoleRegisterImpl
857