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.47 2001/11/05 16:07:48 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     // add the URL (may overwrite an existing one; who cares)
127     directories.add(directoryUrl);
128 
129     // directory URLs shouldn't include "creole.xml"
130     String urlName = directoryUrl.toExternalForm();
131     if(urlName.toLowerCase().endsWith("creole.xml")) {
132       throw new GateException(
133         "CREOLE directory URLs should point to the parent location of " +
134         "the creole.xml file, not the file itself; bad URL was: " + urlName
135       );
136     }
137 
138     // create a URL for the creole.xml file, based on the directory URL
139     URL directoryXmlFileUrl = directoryUrl;
140     String separator = "/";
141     if(urlName.endsWith(separator)) separator = "";
142     try {
143       directoryXmlFileUrl = new URL(urlName + separator + "creole.xml");
144     } catch(MalformedURLException e) {
145       throw(new GateException("bad creole.xml URL, based on " + urlName));
146     }
147 
148     // parse the directory file
149     try {
150       parseDirectory(directoryXmlFileUrl.openStream(), directoryUrl);
151     } catch(IOException e) {
152       throw(new GateException("couldn't open creole.xml: " + e.toString()));
153     }
154   } // registerDirectories(URL)
155 
156   /** Parse a directory file (represented as an open stream), adding
157     * resource data objects to the CREOLE register as they occur.
158     * If the resource is from a URL then that location is passed (otherwise
159     * null).
160     */
161   protected void parseDirectory(InputStream directoryStream, URL directoryUrl)
162   throws GateException
163   {
164     // create a handler for the directory file and parse it;
165     // this will create ResourceData entries in the register
166     try {
167       DefaultHandler handler = new CreoleXmlHandler(this, directoryUrl);
168       parser.parse(directoryStream, handler);
169       if(DEBUG) {
170         Out.prln(
171           "done parsing " +
172           ((directoryUrl == null) ? "null" : directoryUrl.toString())
173         );
174       }
175     } catch (IOException e) {
176       throw(new GateException(e));
177     } catch (SAXException e) {
178       if(DEBUG) Out.println(e.toString());
179       throw(new GateException(e));
180     }
181 
182   } // parseDirectory
183 
184   /** Register resources that are built in to the GATE distribution.
185     * These resources are described by the <TT>creole.xml</TT> file in
186     * <TT>resources/creole</TT>.
187     */
188   public void registerBuiltins() throws GateException {
189     try {
190       parseDirectory(
191         new URL("gate:/creole/creole.xml").openStream(),
192         new URL("gate:/creole/")
193       );
194     } catch(IOException e) {
195       if (DEBUG) Out.println(e);
196       throw(new GateException(e));
197     }
198   } // registerBuiltins()
199 
200   /** This is a utility method for creating CREOLE directory files
201     * (typically called <CODE>creole.xml</CODE>) from a list of Jar
202     * files that contain resources. The method concatenates the
203     * <CODE>resource.xml</CODE> files that the Jars contain.
204     * <P>
205     * If Java allowed class methods in interfaces this would be static.
206     */
207   public File createCreoleDirectoryFile(File directoryFile, Set jarFileNames)
208   {
209     ////////////////////
210     // dump xml header and comment header and <CREOLE-DIRECTORY> into dirfile
211     // for each jar file pick out resource.xml
212     // strip xml header
213     // dump into dirfile
214     // put </CREOLE-DIRECTORY> into dirfile
215     throw new LazyProgrammerException();
216   } // createCreoleDirectoryFile
217 
218   /** Overide HashMap's put method to maintain a list of all the
219     * types of LR in the register, and a list of tool types. The key is
220     * the resource type, the value its data.
221     */
222   public Object put(Object key, Object value) {
223     ResourceData rd = (ResourceData) value;
224 
225     // get the resource implementation class
226     Class resClass = null;
227     try {
228       resClass = rd.getResourceClass();
229     } catch(ClassNotFoundException e) {
230       throw new GateRuntimeException(
231         "Couldn't get resource class from the resource data:" + e
232       );
233     }
234 
235     // add class names to the type lists
236     if(LanguageResource.class.isAssignableFrom(resClass)) {
237       if(DEBUG) Out.prln("LR: " + resClass);
238       if(lrTypes == null) lrTypes = new HashSet(); // for deserialisation
239       lrTypes.add(rd.getClassName());
240     } else if(ProcessingResource.class.isAssignableFrom(resClass)) {
241       if(DEBUG) {
242         Out.prln("PR: " + resClass);
243         //Out.prln("prTypes: " + prTypes);
244         //Out.prln("rd.getClassName(): " + rd.getClassName());
245       }
246       if(prTypes == null) prTypes = new HashSet(); // for deserialisation
247       prTypes.add(rd.getClassName());
248     } else if(VisualResource.class.isAssignableFrom(resClass)) {
249       if(DEBUG) Out.prln("VR: " + resClass);
250       if(vrTypes == null) vrTypes = new LinkedList(); // for deserialisation
251       vrTypes.add(rd.getClassName());
252     }else if(Controller.class.isAssignableFrom(resClass)) {
253       if(DEBUG) Out.prln("Controller: " + resClass);
254       if(controllerTypes == null) controllerTypes = new HashSet(); // for deserialisation
255       controllerTypes.add(rd.getClassName());
256     }
257 
258     // maintain tool types list
259     if(rd.isTool()) {
260       if(toolTypes == null) toolTypes = new HashSet(); // for deserialisation
261       toolTypes.add(rd.getClassName());
262     }
263 
264     return super.put(key, value);
265   } // put(key, value)
266 
267   /** Overide HashMap's delete method to update the lists of types
268     * in the register.
269     */
270   public Object remove(Object key) {
271     ResourceData rd = (ResourceData) get(key);
272     if(rd == null) return null;
273 
274     if(DEBUG) {
275       Out.prln(key);
276       Out.prln(rd);
277     }
278     if(LanguageResource.class.isAssignableFrom(rd.getClass()))
279       lrTypes.remove(rd.getClassName());
280     else if(ProcessingResource.class.isAssignableFrom(rd.getClass()))
281       prTypes.remove(rd.getClassName());
282     else if(VisualResource.class.isAssignableFrom(rd.getClass()))
283       vrTypes.remove(rd.getClassName());
284 
285     // maintain tool types list
286     if(rd.isTool())
287       toolTypes.remove(rd.getClassName());
288 
289     return super.remove(key);
290   } // remove(Object)
291 
292   /** Overide HashMap's clear to update the list of LR types in the register,
293     * and remove all resources and forgets all directories.
294     */
295   public void clear() {
296     lrTypes.clear();
297     prTypes.clear();
298     vrTypes.clear();
299     toolTypes.clear();
300     directories.clear();
301     super.clear();
302   } // clear()
303 
304   /** Get the list of types of LR in the register. */
305   public Set getLrTypes() { return Collections.unmodifiableSet(lrTypes);}
306 
307   /** Get the list of types of PR in the register. */
308   public Set getPrTypes() { return Collections.unmodifiableSet(prTypes);}
309 
310   /** Get the list of types of VR in the register. */
311   public Set getVrTypes() { return Collections.unmodifiableSet(new HashSet(vrTypes));}
312 
313   /** Get the list of types of VR in the register. */
314   public Set getControllerTypes() {
315     return Collections.unmodifiableSet(controllerTypes);
316   }
317 
318   /** Get the list of types of TOOL respurces in the register. */
319   public Set getToolTypes() { return Collections.unmodifiableSet(toolTypes);}
320 
321   /** Get a list of all instantiations of LR in the register. */
322   public List getLrInstances() {
323     Set lrTypeSet = getLrTypes();
324     List instances = new ArrayList();
325 
326     Iterator iter = lrTypeSet.iterator();
327     while(iter.hasNext()) {
328       String type = (String) iter.next();
329       instances.addAll(getLrInstances(type));
330     }// End while
331     return Collections.unmodifiableList(instances);
332   } // getLrInstances()
333 
334   /** Get a list of all instantiations of PR in the register. */
335   public List getPrInstances() {
336     Set prTypeSet = getPrTypes();
337     List instances = new ArrayList();
338 
339     Iterator iter = prTypeSet.iterator();
340     while(iter.hasNext()) {
341       String type = (String) iter.next();
342       instances.addAll(getPrInstances(type));
343     }// End while
344 
345     return Collections.unmodifiableList(instances);
346   } // getPrInstances()
347 
348   /** Get a list of all instantiations of VR in the register. */
349   public List getVrInstances() {
350     Set vrTypeSet = getVrTypes();
351     List instances = new ArrayList();
352 
353     Iterator iter = vrTypeSet.iterator();
354     while(iter.hasNext()) {
355       String type = (String) iter.next();
356       instances.addAll(getVrInstances(type));
357     }// End while
358 
359     return Collections.unmodifiableList(instances);
360   } // getVrInstances()
361 
362   /** Get a list of instantiations of a type of LR in the register. */
363   public List getLrInstances(String resourceTypeName) {
364     ResourceData resData = (ResourceData) get(resourceTypeName);
365     if(resData == null)
366       return Collections.unmodifiableList(new ArrayList());
367 
368     return Collections.unmodifiableList(resData.getInstantiations());
369   } // getLrInstances
370 
371   /** Get a list of instantiations of a type of PR in the register. */
372   public List getPrInstances(String resourceTypeName) {
373     ResourceData resData = (ResourceData) get(resourceTypeName);
374     if(resData == null)
375       return Collections.unmodifiableList(new ArrayList());
376 
377     return Collections.unmodifiableList(resData.getInstantiations());
378   } // getPrInstances
379 
380   /** Get a list of instantiations of a type of VR in the register. */
381   public List getVrInstances(String resourceTypeName) {
382     ResourceData resData = (ResourceData) get(resourceTypeName);
383     if(resData == null)
384       return Collections.unmodifiableList(new ArrayList());
385 
386     return Collections.unmodifiableList(resData.getInstantiations());
387   } // getVrInstances
388 
389   /** Get a list of all non-private instantiations of LR in the register. */
390   public List getPublicLrInstances() {
391     return Collections.unmodifiableList(getPublics(getLrInstances()));
392   }// getPublicLrInstances()
393 
394   /** Get a list of all non-private instantiations of PR in the register. */
395   public List getPublicPrInstances() {
396     return Collections.unmodifiableList(getPublics(getPrInstances()));
397   }// getPublicPrInstances()
398 
399   /** Get a list of all non-private instantiations of VR in the register. */
400   public List getPublicVrInstances() {
401     return Collections.unmodifiableList(getPublics(getVrInstances()));
402   }//getPublicVrInstances()
403 
404   /** Get a list of all non-private types of LR in the register. */
405   public List getPublicLrTypes() {
406     return Collections.unmodifiableList(getPublicTypes(getLrTypes()));
407   }//getPublicLrTypes()
408 
409   /** Get a list of all non-private types of PR in the register. */
410   public List getPublicPrTypes() {
411     return Collections.unmodifiableList(getPublicTypes(getPrTypes()));
412   }//getPublicPrTypes()
413 
414   /** Get a list of all non-private types of VR in the register. */
415   public List getPublicVrTypes() {
416     return Collections.unmodifiableList(getPublicTypes(getVrTypes()));
417   }//getPublicVrTypes()
418 
419   /** Get a list of all non-private types of controller in the register. */
420   public List getPublicControllerTypes() {
421     return Collections.unmodifiableList(getPublicTypes(getControllerTypes()));
422   }//getPublicPrTypes()
423 
424 
425   /**
426    * Gets all the instantiations of a given type and all its derivate types;
427    * It doesn't return instances that have the hidden attribute set to "true"
428    */
429   public List getAllInstances(String type) throws GateException{
430     Iterator typesIter = keySet().iterator();
431     List res = new ArrayList();
432     Class targetClass;
433     try{
434       targetClass = Gate.getClassLoader().loadClass(type);
435     }catch(ClassNotFoundException cnfe){
436       throw new GateException("Invalid type " + type);
437     }
438     while(typesIter.hasNext()){
439       String aType = (String)typesIter.next();
440       Class aClass;
441       try{
442         aClass = Gate.getClassLoader().loadClass(aType);
443         if(targetClass.isAssignableFrom(aClass)){
444           //filter out hidden instances
445           Iterator newInstancesIter = ((ResourceData)get(aType)).
446                                       getInstantiations().iterator();
447           while(newInstancesIter.hasNext()){
448             Resource instance = (Resource)newInstancesIter.next();
449             if(!Gate.getHiddenAttribute(instance.getFeatures())){
450               res.add(instance);
451             }
452           }
453         }
454       }catch(ClassNotFoundException cnfe){
455         throw new LuckyException(
456           "A type registered in the creole register does not exist in the VM!");
457       }
458 
459     }//while(typesIter.hasNext())
460 
461     return res;
462   }
463 
464   /**
465    * Returns a list of strings representing class names for large VRs valid
466    * for a given type of language/processing resource.
467    * The default VR will be the first in the returned list.
468    * @param resoureClassName the name of the resource that has large viewers. If
469    * resourceClassName is <b>null</b> then an empty list will be returned.
470    * @return a list with Strings representing the large VRs for the
471    * resourceClassName
472    */
473   public List getLargeVRsForResource(String resourceClassName){
474     return getVRsForResource(resourceClassName, ResourceData.LARGE_GUI);
475   }// getLargeVRsForResource()
476 
477   /**
478    * Returns a list of strings representing class names for small VRs valid
479    * for a given type of language/processing resource
480    * The default VR will be the first in the returned list.
481    * @param resoureClassName the name of the resource that has large viewers. If
482    * resourceClassName is <b>null</b> then an empty list will be returned.
483    * @return a list with Strings representing the large VRs for the
484    * resourceClassName
485    */
486   public List getSmallVRsForResource(String resourceClassName){
487     return getVRsForResource(resourceClassName, ResourceData.SMALL_GUI);
488   }// getSmallVRsForResource
489 
490   /**
491    * Returns a list of strings representing class names for guiType VRs valid
492    * for a given type of language/processing resource
493    * The default VR will be the first in the returned list.
494    * @param resoureClassName the name of the resource that has large viewers. If
495    * resourceClassName is <b>null</b> then an empty list will be returned.
496    * @param guiType can be ResourceData's LARGE_GUI or SMALL_GUI
497    * @return a list with Strings representing the large VRs for the
498    * resourceClassName
499    */
500   private List getVRsForResource(String resourceClassName, int guiType){
501     // If resurceClassName is null return a simply list
502     if (resourceClassName == null)
503       return Collections.unmodifiableList(new ArrayList());
504     // create a Class object for the resource
505     Class resourceClass = null;
506     GateClassLoader classLoader = Gate.getClassLoader();
507     try{
508       resourceClass = classLoader.loadClass(resourceClassName);
509     } catch (ClassNotFoundException ex){
510       throw new GateRuntimeException(
511         "Couldn't get resource class from the resource name:" + ex
512       );
513     }// End try
514     LinkedList responseList = new LinkedList();
515     String defaultVR = null;
516     // Take all VRs and for each large one, test if
517     // resourceClassName is asignable form VR's RESOURCE_DISPLAYED
518     Iterator vrIterator = vrTypes.iterator();
519     while (vrIterator.hasNext()){
520       String vrClassName = (String) vrIterator.next();
521       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
522       if (vrResourceData == null)
523         throw new GateRuntimeException(
524           "Couldn't get resource data for VR called " + vrClassName
525         );
526       if (vrResourceData.getGuiType() == guiType){
527         String resourceDisplayed = vrResourceData.getResourceDisplayed();
528         if (resourceDisplayed != null){
529           Class resourceDisplayedClass = null;
530           try{
531             resourceDisplayedClass = classLoader.loadClass(resourceDisplayed);
532           } catch (ClassNotFoundException ex){
533               throw new GateRuntimeException(
534                 "Couldn't get resource class from the resource name :" +
535                 resourceDisplayed + " " +ex );
536           }// End try
537           if (resourceDisplayedClass.isAssignableFrom(resourceClass)){
538             responseList.add(vrClassName);
539             if (vrResourceData.isMainView()){
540               defaultVR = vrClassName;
541             }// End if
542           }// End if
543         }// End if
544       }// End if
545     }// End while
546     if (defaultVR != null){
547       responseList.remove(defaultVR);
548       responseList.addFirst(defaultVR);
549     }// End if
550     return Collections.unmodifiableList(responseList);
551   }// getVRsForResource()
552 
553   /**
554    * Returns a list of strings representing class names for annotation VRs
555    * that are able to display/edit all types of annotations.
556    * The default VR will be the first in the returned list.
557    * @return a list with all VRs that can display all annotation types
558    */
559   public List getAnnotationVRs(){
560     LinkedList responseList = new LinkedList();
561     String defaultVR = null;
562     Iterator vrIterator = vrTypes.iterator();
563     while (vrIterator.hasNext()){
564       String vrClassName = (String) vrIterator.next();
565       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
566       if (vrResourceData == null)
567         throw new GateRuntimeException(
568           "Couldn't get resource data for VR called " + vrClassName
569         );
570       Class vrResourceClass = null;
571       try{
572         vrResourceClass = vrResourceData.getResourceClass();
573       } catch(ClassNotFoundException ex){
574         throw new GateRuntimeException(
575           "Couldn't create a class object for VR called " + vrClassName
576         );
577       }// End try
578       // Test if VR can display all types of annotations
579       if ( vrResourceData.getGuiType() == ResourceData.NULL_GUI &&
580            vrResourceData.getAnnotationTypeDisplayed() == null &&
581            vrResourceData.getResourceDisplayed() == null &&
582            gate.creole.AnnotationVisualResource.class.
583                                           isAssignableFrom(vrResourceClass)){
584 
585           responseList.add(vrClassName);
586           if (vrResourceData.isMainView())
587               defaultVR = vrClassName;
588       }// End if
589     }// End while
590     if (defaultVR != null){
591       responseList.remove(defaultVR);
592       responseList.addFirst(defaultVR);
593     }// End if
594     return Collections.unmodifiableList(responseList);
595   }// getAnnotationVRs()
596 
597   /**
598    * Returns a list of strings representing class names for annotation VRs
599    * that are able to display/edit a given annotation type
600    * The default VR will be the first in the returned list.
601    */
602   public List getAnnotationVRs(String annotationType){
603     if (annotationType == null)
604       return Collections.unmodifiableList(new ArrayList());
605     LinkedList responseList = new LinkedList();
606     String defaultVR = null;
607     Iterator vrIterator = vrTypes.iterator();
608     while (vrIterator.hasNext()){
609       String vrClassName = (String) vrIterator.next();
610       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
611       if (vrResourceData == null)
612         throw new GateRuntimeException(
613           "Couldn't get resource data for VR called " + vrClassName
614         );
615       Class vrResourceClass = null;
616       try{
617         vrResourceClass = vrResourceData.getResourceClass();
618       } catch(ClassNotFoundException ex){
619         throw new GateRuntimeException(
620           "Couldn't create a class object for VR called " + vrClassName
621         );
622       }// End try
623       // Test if VR can display all types of annotations
624       if ( vrResourceData.getGuiType() == ResourceData.NULL_GUI &&
625            vrResourceData.getAnnotationTypeDisplayed() != null &&
626            gate.creole.AnnotationVisualResource.class.
627                                           isAssignableFrom(vrResourceClass)){
628 
629           String annotationTypeDisplayed =
630                                   vrResourceData.getAnnotationTypeDisplayed();
631           if (annotationTypeDisplayed.equals(annotationType)){
632             responseList.add(vrClassName);
633             if (vrResourceData.isMainView())
634               defaultVR = vrClassName;
635           }// End if
636       }// End if
637     }// End while
638     if (defaultVR != null){
639       responseList.remove(defaultVR);
640       responseList.addFirst(defaultVR);
641     }// End if
642     return Collections.unmodifiableList(responseList);
643   }//getAnnotationVRs()
644 
645   /**
646    * Returns a list of strings representing annotations types for which
647    * there are custom viewers/editor registered.
648    */
649   public List getVREnabledAnnotationTypes(){
650     LinkedList responseList = new LinkedList();
651     Iterator vrIterator = vrTypes.iterator();
652     while (vrIterator.hasNext()){
653       String vrClassName = (String) vrIterator.next();
654       ResourceData vrResourceData = (ResourceData) this.get(vrClassName);
655       if (vrResourceData == null)
656         throw new GateRuntimeException(
657           "Couldn't get resource data for VR called " + vrClassName
658         );
659       // Test if VR can display all types of annotations
660       if ( vrResourceData.getGuiType() == ResourceData.NULL_GUI &&
661            vrResourceData.getAnnotationTypeDisplayed() != null ){
662 
663           String annotationTypeDisplayed =
664                                   vrResourceData.getAnnotationTypeDisplayed();
665           responseList.add(annotationTypeDisplayed);
666       }// End if
667     }// End while
668     return Collections.unmodifiableList(responseList);
669   }// getVREnabledAnnotationTypes()
670 
671 
672 
673   /** Get a list of all non-private instantiations. */
674   protected List getPublics(List instances) {
675     Iterator iter = instances.iterator();
676     List publics = new ArrayList();
677 
678     // for each instance, if resource data specifies it isn't private,
679     // add to the publics list
680     while(iter.hasNext()) {
681       Resource res = (Resource) iter.next();
682       ResourceData rd = (ResourceData) get(res.getClass().getName());
683       if(! rd.isPrivate()) publics.add(res);
684     }
685 
686     return Collections.unmodifiableList(publics);
687   } // getPublics
688 
689   /** Gets a list of all non private types from alist of types*/
690   protected List getPublicTypes(Collection types){
691     Iterator iter = types.iterator();
692     List publics = new ArrayList();
693     while(iter.hasNext()){
694       String oneType = (String)iter.next();
695       ResourceData rData = (ResourceData)get(oneType);
696       if(rData != null && !rData.isPrivate()) publics.add(oneType);
697     }
698     return Collections.unmodifiableList(publics);
699   }//getPublicTypes
700 
701   public synchronized void removeCreoleListener(CreoleListener l) {
702     if (creoleListeners != null && creoleListeners.contains(l)) {
703       Vector v = (Vector) creoleListeners.clone();
704       v.removeElement(l);
705       creoleListeners = v;
706     }
707   }
708 
709   public synchronized void addCreoleListener(CreoleListener l) {
710     Vector v = creoleListeners == null ? new Vector(2) : (Vector) creoleListeners.clone();
711     if (!v.contains(l)) {
712       v.addElement(l);
713       creoleListeners = v;
714     }
715   } // getPublicTypes
716 
717   /**
718    * Removes a {@link gate.event.CreoleListener} previously registered with this
719    * CreoleRegister. {@see #addCreoleListener()}
720    */
721 
722   /**
723    * Registers a {@link gate.event.CreoleListener}with this CreoleRegister.
724    * The register will fire events every time a resource is added to or removed
725    * from the system.
726    */// addCreoleListener
727 
728   /**
729    * Notifies all listeners that a new {@link gate.Resource} has been loaded
730    * into the system
731    */// fireResourceLoaded
732 
733   /**
734    * Notifies all listeners that a {@link gate.Resource} has been unloaded
735    * from the system
736    */// fireResourceUnloaded
737 
738   /** A list of the types of LR in the register. */
739   protected Set lrTypes;
740 
741   /** A list of the types of PR in the register. */
742   protected Set prTypes;
743 
744   /** A list of the types of VR in the register. */
745   protected List vrTypes;
746 
747   /** A list of the types of VR in the register. */
748   protected Set controllerTypes;
749 
750   /** A list of the types of TOOL in the register. */
751   protected Set toolTypes;
752 
753   private transient Vector creoleListeners;
754   protected void fireResourceLoaded(CreoleEvent e) {
755     if (creoleListeners != null) {
756       Vector listeners = creoleListeners;
757       int count = listeners.size();
758       for (int i = 0; i < count; i++) {
759         ((CreoleListener) listeners.elementAt(i)).resourceLoaded(e);
760       }
761     }
762   }
763   protected void fireResourceUnloaded(CreoleEvent e) {
764     if (creoleListeners != null) {
765       Vector listeners = creoleListeners;
766       int count = listeners.size();
767       for (int i = 0; i < count; i++) {
768         ((CreoleListener) listeners.elementAt(i)).resourceUnloaded(e);
769       }
770     }
771   }
772   protected void fireDatastoreOpened(CreoleEvent e) {
773     if (creoleListeners != null) {
774       Vector listeners = creoleListeners;
775       int count = listeners.size();
776       for (int i = 0; i < count; i++) {
777         ((CreoleListener) listeners.elementAt(i)).datastoreOpened(e);
778       }
779     }
780   }
781   protected void fireDatastoreCreated(CreoleEvent e) {
782     if (creoleListeners != null) {
783       Vector listeners = creoleListeners;
784       int count = listeners.size();
785       for (int i = 0; i < count; i++) {
786         ((CreoleListener) listeners.elementAt(i)).datastoreCreated(e);
787       }
788     }
789   }
790 
791   protected void fireDatastoreClosed(CreoleEvent e) {
792     if (creoleListeners != null) {
793       Vector listeners = creoleListeners;
794       int count = listeners.size();
795       for (int i = 0; i < count; i++) {
796         ((CreoleListener) listeners.elementAt(i)).datastoreClosed(e);
797       }
798     }
799   }
800 
801   public void resourceLoaded(CreoleEvent e) {
802     fireResourceLoaded(e);
803   }
804 
805   public void resourceUnloaded(CreoleEvent e) {
806     fireResourceUnloaded(e);
807   }
808 
809   public void datastoreOpened(CreoleEvent e) {
810     fireDatastoreOpened(e);
811   }
812 
813   public void datastoreCreated(CreoleEvent e) {
814     fireDatastoreCreated(e);
815   }
816 
817   public void datastoreClosed(CreoleEvent e) {
818     fireDatastoreClosed(e);
819   }
820 
821   /**The lists of listeners registered with this CreoleRegister*/
822 } // class CreoleRegisterImpl
823