View Javadoc

1   package org.astrogrid.registry.client.query;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   
6   import java.net.URL;
7   import java.util.Vector;
8   import javax.xml.parsers.DocumentBuilder;
9   import javax.xml.parsers.DocumentBuilderFactory;
10  import javax.xml.parsers.ParserConfigurationException;
11  import java.io.IOException;
12  import org.apache.axis.client.Call;
13  import org.apache.axis.client.Service;
14  import org.apache.axis.message.SOAPBodyElement;
15  import org.apache.axis.utils.XMLUtils;
16  //import org.astrogrid.datacenter.query.Sql2Adql;
17  import org.w3c.dom.Document;
18  import org.w3c.dom.NodeList;
19  import org.w3c.dom.Node;
20  import org.w3c.dom.Element;
21  import java.io.Reader;
22  import java.io.StringReader;
23  import org.xml.sax.InputSource;
24  import java.text.SimpleDateFormat;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.Calendar;
29  import java.util.List;
30  import java.util.Iterator;
31  import java.util.Date;
32  import java.text.SimpleDateFormat;
33  import java.net.MalformedURLException;
34  import org.astrogrid.registry.RegistryException;
35  import org.astrogrid.registry.common.XSLHelper;
36  import org.astrogrid.registry.common.InterfaceType;
37  
38  import org.astrogrid.util.DomHelper;
39  
40  import javax.xml.namespace.QName;
41  import javax.xml.rpc.ServiceException;
42  import javax.wsdl.xml.WSDLReader;
43  import javax.wsdl.*;
44  import javax.wsdl.extensions.ExtensibilityElement;
45  import javax.wsdl.extensions.soap.SOAPAddress;
46  
47  import org.xml.sax.SAXException;
48  import java.rmi.RemoteException;
49  
50  import org.astrogrid.registry.common.WSDLBasicInformation;
51  
52  import javax.wsdl.factory.WSDLFactory;
53  
54  import org.astrogrid.config.Config;
55  import org.astrogrid.store.Ivorn;
56  
57  /*** 
58   * The QueryRegistry class is a delegate to a web service that submits an XML formatted
59   * registry query to the to the server side web service also named the same RegistryService.
60   * This delegate helps the user browse the registry and also the OAI. 
61   * 
62   * @see org.astrogrid.registry.common.RegistryInterface
63   * @link http://www.ivoa.net/twiki/bin/view/IVOA/IVOARegWp03
64   * @author Kevin Benson
65   */
66  public class QueryRegistry implements RegistryService {
67  
68      /***
69       * Commons Logger for this class
70       */
71      private static final Log logger = LogFactory.getLog(QueryRegistry.class);
72      
73      private static String reg_default_version = "0.9";
74      
75      private static String reg_transform_version = "0.9";
76  
77     /***
78      * target end point is the location of the webservice. 
79      */
80     private URL endPoint = null;
81  
82     private boolean useCache = false;
83  
84     private static final String NAMESPACE_URI =
85        "http://www.ivoa.net/schemas/services/QueryRegistry/wsdl";
86  
87     private static final String QUERY_URL_PROPERTY =
88        "org.astrogrid.registry.query.endpoint";
89  
90     public static Config conf = null;
91  
92     //@todo don't think it's necessary to hang onto this object
93     static {
94        if (conf == null) {
95           conf = org.astrogrid.config.SimpleConfig.getSingleton();
96           reg_default_version = conf.getString("org.astrogrid.registry.version","0.9"); 
97           reg_transform_version = conf.getString("org.astrogrid.registry.result.version","0.9");
98        }
99     }
100 
101    /***
102     * @todo - I think this is almost cyclic. 
103     * Empty constructor that defaults the end point to local host.
104     * @author Kevin Benson
105     */
106    public QueryRegistry() {
107       this(conf.getUrl(org.astrogrid.registry.client.RegistryDelegateFactory.QUERY_URL_PROPERTY,null));
108    }
109    
110 
111    /***
112     * Main constructor to allocate the endPoint variable.
113     * @param endPoint location to the web service.
114     * @author Kevin Benson
115     */
116    public QueryRegistry(URL endPoint) {
117         logger
118                 .info("QueryRegistry(URL) - entered const(url) of RegistryService");
119       this.endPoint = endPoint;
120       if (this.endPoint == null) {
121           logger.warn("endpoint is null, using cache");
122          useCache = true;
123       }
124         logger
125              .info("QueryRegistry(URL) - exiting const(url) of RegistryService");
126    }
127 
128    /***
129     * Method to establish a Service and a Call to the server side web service.
130     * @return Call object which has the necessary properties set for an Axis message style.
131     * @throws Exception
132     * @todo there's code similar to this in eac of the delegate classes. could it be moved into a common baseclass / helper class.
133     * @author Kevin Benson
134     */
135    private Call getCall() throws ServiceException {
136        
137       logger.info("getCall() - entered getCall()");
138       Call _call = null;
139       Service service = new Service();
140       _call = (Call)service.createCall();
141       _call.setTargetEndpointAddress(this.endPoint);
142       _call.setSOAPActionURI("");
143       _call.setOperationStyle(org.apache.axis.enum.Style.MESSAGE);
144       _call.setOperationUse(org.apache.axis.enum.Use.LITERAL);
145       _call.setEncodingStyle(null);
146       return _call;
147    }
148 
149    /***
150     * To perform a query with ADQL, using adqls.
151     * @param adql string form of adqls
152     * @
153     * @return XML DOM of Resources queried from the registry.
154     * @todo throw registry exception until this method is implemented.
155     * @throws RegistryException problem during the query servor or client side.
156     */
157    public Document searchFromSADQL(String adql) throws RegistryException {
158       //send to sadql->adql parser.
159       //call return search(adql);
160        throw new RegistryException("Not implemented yet");
161        /*
162        try {
163            String adqlString = Sql2Adql.translateToAdql074(adql);
164            return search(DomHelper.newDocument(adqlString));
165        }catch(Exception e) {
166            throw new RegistryException(e);
167        }
168        */
169        //throw new RegistryException("Cannot get to this point");
170    }
171 
172    /***
173     * To perform a query with ADQL, using adql string.
174     * @param adql string form of adql (xml)
175     * @return XML DOM of Resources queried from the registry.
176     * @throws RegistryException problem during the query servor or client side.
177     */   
178    public Document search(String xadql) throws RegistryException {
179       //search using adqlx. Catch any exceptions and throw them as RegistryExceptions
180       try {
181          return search(DomHelper.newDocument(xadql));
182       } catch (ParserConfigurationException pce) {
183          throw new RegistryException(pce);
184       } catch (IOException ioe) {
185          throw new RegistryException(ioe);
186       } catch (SAXException sax) {
187          throw new RegistryException(sax);
188       }
189    }
190    
191    /***
192     * To perform a query on the Registry using a DOM conforming of ADQL.
193     * Uses a Axis-Message type style so wrap the DOM in the method name conforming
194     * to the WSDL.
195     * @param adql string form of adqls
196     * @return XML DOM of Resources queried from the registry.
197     * @throws RegistryException problem during the query servor or client side.
198     */   
199    public Document search(Document adql) throws RegistryException {
200       //wrap a Search element around the dom.
201       //Element currentRoot = adql.getDocumentElement();
202       Document resultDoc = null;
203       Element newRoot = adql.createElementNS(NAMESPACE_URI, "Search");
204       String value = "http://www.ivoa.net/xml/VOResource/v" + reg_default_version;
205       newRoot.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:vr",value);
206       NodeList nl = adql.getElementsByTagNameNS("*","Where");
207       
208       Element currentRoot = null;
209       if(nl.getLength() > 0) {
210           currentRoot = (Element)nl.item(0);
211           //newRoot.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:ad",currentRoot.getNamespaceURI());
212       }      
213       newRoot.appendChild(currentRoot);
214       adql.removeChild(adql.getDocumentElement());
215       adql.appendChild(newRoot);
216       System.out.println("THE ADQL IN SEARCH = " + DomHelper.DocumentToString(adql));
217       try {
218           return callService(adql,"Search","Search");
219       } catch (RemoteException re) {
220          QueryRegistry qr = new QueryRegistry(conf.getUrl(org.astrogrid.registry.client.RegistryDelegateFactory.ALTQUERY_URL_PROPERTY,null));
221          try {
222              return qr.callService(adql,"Search","Search");
223          }catch(RemoteException re2) {
224              throw new RegistryException(re2);    
225          }catch(ServiceException se2) {
226              throw new RegistryException(se2);
227          }catch(Exception e2) {
228              throw new RegistryException(e2);
229          }
230       } catch(ServiceException se) {
231           throw new RegistryException(se);
232       } catch(Exception e) {
233           throw new RegistryException(e);
234       }
235    }
236    
237    protected Document callService(Document soapBody, String name, String soapActionURI) throws RemoteException, ServiceException, Exception {
238        Vector result = null;
239        Document resultDoc = null;
240            //get a call object
241            Call call = getCall();
242            call.setSOAPActionURI(soapActionURI);
243            //create the soap body to be placed in the
244            //outgoing soap message.
245            SOAPBodyElement sbeRequest =
246               new SOAPBodyElement(soapBody.getDocumentElement());
247            //go ahead and set the name and namespace on the soap body
248            //not sure if this is that important.
249            sbeRequest.setName(name);
250            sbeRequest.setNamespaceURI(NAMESPACE_URI);
251            //call the web service, on axis-message style it
252            //comes back as a vector of soabodyelements.
253            result = (Vector)call.invoke(new Object[] { sbeRequest });
254            SOAPBodyElement sbe = null;
255            if (result.size() > 0) {
256               sbe = (SOAPBodyElement)result.get(0);
257               resultDoc = sbe.getAsDocument();
258               if(!reg_default_version.replace('_','.').equals(reg_transform_version.replace('_','.'))) {
259                   System.out.println("performing tranformation = " + reg_transform_version + 
260                                      " default version = " + reg_default_version);
261                   XSLHelper xslHelper = new XSLHelper();
262                   return xslHelper.transformResourceToResource(resultDoc.getDocumentElement(),
263                               reg_default_version,reg_transform_version);
264               }//if
265               return resultDoc;            
266            }
267            return null;
268    }
269    
270    /***
271     * Performas a query to return all Resources of a type of Registry.
272     * @return XML DOM of Resources queried from the registry.
273     * @throws RegistryException problem during the query servor or client side.
274     */
275    public Document getRegistries() throws RegistryException {
276        Document doc = null;
277        Document resultDoc = null;
278 
279        try {
280           logger.info("getRegistries() - creating full soap element.");
281           doc = DomHelper.newDocument();
282           //@todo GetRegistries should be a constant.
283           Element root = doc.createElementNS(NAMESPACE_URI, "GetRegistries");
284           String value = "http://www.ivoa.net/xml/VOResource/v" + reg_default_version.replace('_','.');
285           root.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:vr",value);          
286           doc.appendChild(root);
287        } catch (ParserConfigurationException pce) {
288           throw new RegistryException(pce);
289        }
290        
291        try {
292           return callService(doc,"GetRegistries","GetRegistries");
293        } catch (RemoteException re) {
294           throw new RegistryException(re);
295        } catch (ServiceException se) {
296           throw new RegistryException(se);
297        } catch (Exception e) {
298           throw new RegistryException(e);
299        }
300    }
301    
302    /***
303     * Identify - Queryies based on OAI-Identify verb, identifying the repository.
304     * @return XML DOM of an OAI-PMH for the Identify. 
305     */   
306    public Document identify() throws RegistryException {
307       Document doc = null;
308       Document resultDoc = null;
309 
310       try {
311          logger.info("identify() - creating full soap element.");
312          doc = DomHelper.newDocument();
313          Element root = doc.createElementNS(NAMESPACE_URI, "Identify");
314          doc.appendChild(root);
315       } catch (ParserConfigurationException pce) {
316          throw new RegistryException(pce);
317       }
318       
319       try {
320          return callService(doc,"Identify","Identify");
321       } catch (RemoteException re) {
322          throw new RegistryException(re);
323       } catch (ServiceException se) {
324          throw new RegistryException(se);
325       } catch (Exception e) {
326          throw new RegistryException(e);
327       }
328    }
329    
330 
331    /***
332     * ListRecords - OAI ListRecords query, the Registry server will default the
333     * metadataPrefix to ivo_vor. 
334     * @return XML DOM of an OAI-PMH for the ListRecords. 
335     */
336    public Document listRecords() throws RegistryException {
337    	return listRecords(null,null,null);
338    }
339    
340    /***
341     * ListRecords - OAI ListRecords query based on a fromDate, the recods
342     * changed from that date The Registry server will default the
343     * metadataPrefix to ivo_vor
344     * @param fromDate - A from date for returning Resources from a date till now. 
345     * @return XML DOM of an OAI-PMH for the ListRecords. 
346     */
347    public Document listRecords(Date fromDate) throws RegistryException {
348    	return listRecords(null,fromDate,null);    
349    }
350    
351    /***
352     * ListRecords - OAI ListRecords query. This will be the most used OAI verb for harvesting.
353     * @param metadataPrefix - oai metadataPrefix string normally ivo_vor or oai_dc. 
354     * A null will let the Registry server default it to ivo_vor. 
355     * @param fromDate - A from date for returning Resources from a date till now. 
356     * @param untilDate - Returning resources from the beginning till a date. 
357     * @return XML DOM of an OAI-PMH for the ListRecords. 
358     */
359    public Document listRecords(String metadataPrefix, Date fromDate, Date untilDate) throws RegistryException {
360       Document doc = null;
361       Document resultDoc = null;
362 
363       try {
364          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
365           
366          logger
367                .info("listRecords(String, Date, Date) - creating full soap element.");
368          doc = DomHelper.newDocument();
369          Element root = doc.createElementNS(NAMESPACE_URI, "ListRecords");
370          doc.appendChild(root);
371          Element temp = null;
372          //Create the other xml elements in the soap body if they are present
373          if(metadataPrefix != null && metadataPrefix.trim().length() > 0) {
374          	temp = doc.createElement("metadataPrefix");
375             temp.appendChild(doc.createTextNode(metadataPrefix));
376             root.appendChild(temp);    
377          }         
378          if(fromDate != null) {
379             temp = doc.createElement("from");
380             temp.appendChild(doc.createTextNode(sdf.format(fromDate)));
381             root.appendChild(temp);
382          }
383          if(untilDate != null) {
384             temp = doc.createElement("until");
385             temp.appendChild(doc.createTextNode(sdf.format(untilDate)));
386             root.appendChild(temp);            
387          }
388       } catch (ParserConfigurationException pce) {
389          throw new RegistryException(pce);
390       }
391       
392       try {
393           return callService(doc,"ListRecords","ListRecords");
394       } catch (RemoteException re) {
395          throw new RegistryException(re);
396       } catch (ServiceException se) {
397          throw new RegistryException(se);
398       } catch (Exception e) {
399          throw new RegistryException(e);
400       }
401    }
402    
403    /***
404     * ListMetadataFormats - OAI ListMetadtaFormats verb call.  With an optional
405     * identifier string to list the metadata formats for a particular id.
406     * @return XML DOM of an OAI-PMH for the ListMetadataFormats. 
407     */
408    public Document listMetadataFormats(String identifier) throws RegistryException {
409       Document doc = null;
410       Document resultDoc = null;
411 
412       try {
413           
414          logger
415               .info("listMetadataFormats(String) - creating full soap element.");
416          doc = DomHelper.newDocument();
417          Element root = doc.createElementNS(NAMESPACE_URI, "ListMetadataFormats");
418          doc.appendChild(root);
419          if(identifier != null || identifier.trim().length() > 0) {          
420              Element temp = doc.createElement("identifier");
421              temp.appendChild(doc.createTextNode(identifier));
422              root.appendChild(temp);
423          }
424       } catch (ParserConfigurationException pce) {
425          throw new RegistryException(pce);
426       }
427       
428       try {
429           return callService(doc,"ListMetadataFormats","ListMetadataFormats");
430       } catch (RemoteException re) {
431          throw new RegistryException(re);
432       } catch (ServiceException se) {
433          throw new RegistryException(se);
434       } catch (Exception e) {
435          throw new RegistryException(e);
436       }
437    }
438    
439    /***
440     * OAI - Get a specific record from OAI given an identifier. 
441     * Defaults the metadataPrefix to ivo_vor.
442     * @param identifier for a particular record ex: ivo_vor://astrogrid.org/Registry
443     * 
444     * @return XML DOM of an OAI-PMH for the GetRecord. 
445     */
446    public Document getRecord(String identifier) throws RegistryException {
447    	return getRecord(identifier,null);
448    }
449    
450    /***
451     * OAI - Get a specefic record for an identifier and metadataprefix
452     * @param identifier for a particular record ex: ivo_vor://astrogrid.org/Registry
453     * @param metadataPrefix is the oai prefix/id to be used, currently only ivo_vor and oai_dc. 
454     * @return XML DOM of an OAI-PMH for the GetRecord. 
455     */
456    public Document getRecord(String identifier, String metadataPrefix) throws RegistryException {
457       Document doc = null;
458       Document resultDoc = null;
459 
460       try {
461          logger
462               .info("getRecord(String, String) - creating full soap element.");
463          doc = DomHelper.newDocument();
464          Element root = doc.createElementNS(NAMESPACE_URI, "GetRecord");
465          doc.appendChild(root);
466          Element temp = null;
467          if(identifier == null || identifier.trim().length() <= 0) 
468             throw new RegistryException("Error From Client: No identifier found for calling GetRecord");
469          
470          temp = doc.createElement("identifier");
471          temp.appendChild(doc.createTextNode(identifier));
472          root.appendChild(temp);    
473 
474          if(metadataPrefix != null && metadataPrefix.trim().length() > 0) {
475             temp = doc.createElement("metadataPrefix");
476             temp.appendChild(doc.createTextNode(metadataPrefix));
477             root.appendChild(temp);    
478          }         
479  
480       } catch (ParserConfigurationException pce) {
481          throw new RegistryException(pce);
482       }
483       
484       try {
485           return callService(doc,"GetRecord","GetRecord");
486       } catch (RemoteException re) {
487          throw new RegistryException(re);
488       } catch (ServiceException se) {
489          throw new RegistryException(se);
490       } catch (Exception e) {
491          throw new RegistryException(e);
492       }
493    }
494    
495    /***
496     * OAI - ListIdentifiers call, similiar to ListRecords but only returns
497     * the identifiers (unique ids) for the records. Defaults the metadataPrefix to
498     * ivo_vor.
499     * 
500     * @return XML DOM of an OAI-PMH for the ListIdentifiers. 
501     */
502    public Document listIdentifiers() throws RegistryException {
503    	return listIdentifiers(null,null,null);
504    }
505    
506    /***
507     * OAI - ListIdentifiers call, similiar to ListRecords but only returns
508     * the identifiers (unique ids) for the records. Defaults the metadataPrefix to
509     * ivo_vor.
510     * @param metadataPrefix the oai prefix; normally ivo_vor.  Also available is oai_dc.
511     * @param fromDate - A from date for returning Resources from a date till now. 
512     * @param untilDate - Returning resources from the beginning till a date.
513     * @return XML DOM of an OAI-PMH for the ListIdentifiers. 
514     */
515    public Document listIdentifiers(String metadataPrefix, Date fromDate, Date untilDate) throws RegistryException {
516       Document doc = null;
517       Document resultDoc = null;
518 
519       try {
520          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
521           
522          logger
523               .info("listIdentifiers(String, Date, Date) - creating full soap element.");
524          doc = DomHelper.newDocument();
525          Element root = doc.createElementNS(NAMESPACE_URI, "ListIdentifiers");
526          doc.appendChild(root);
527          Element temp = null;
528          if(metadataPrefix != null && metadataPrefix.trim().length() > 0) {
529             temp = doc.createElement("metadataPrefix");
530             temp.appendChild(doc.createTextNode(metadataPrefix));
531             root.appendChild(temp);    
532          }         
533          if(fromDate != null) {
534             temp = doc.createElement("from");
535             temp.appendChild(doc.createTextNode(sdf.format(fromDate)));
536             root.appendChild(temp);
537          }
538          if(untilDate != null) {
539             temp = doc.createElement("until");
540             temp.appendChild(doc.createTextNode(sdf.format(untilDate)));
541             root.appendChild(temp);            
542          }
543       } catch (ParserConfigurationException pce) {
544          throw new RegistryException(pce);
545       }
546       
547       try {
548           return callService(doc,"ListIdentifiers","ListIdentifiers");
549       } catch (RemoteException re) {
550          throw new RegistryException(re);
551       } catch (ServiceException se) {
552          throw new RegistryException(se);
553       } catch (Exception e) {
554          throw new RegistryException(e);
555       }
556    }   
557 
558    /***
559     * Old style xml in string form to perform a query. To be deprecated soon, but currently
560     * other astrogrid components use this method.  Created before the standard of ADQL.
561     * @param the xml string version of the old style astrogrid query language
562     * for the registry..
563     * @return XML DOM of Resources queried from the registry. 
564     */
565    public Document submitQuery(String query) throws RegistryException {
566        
567       logger.info("submitQuery(String) - entered submitQueryStringDOM()");
568       try {
569          return submitQuery(DomHelper.newDocument(query));
570       } catch (ParserConfigurationException pce) {
571          throw new RegistryException(pce);
572       } catch (IOException ioe) {
573          throw new RegistryException(ioe);
574       } catch (SAXException sax) {
575          throw new RegistryException(sax);
576       }
577    }
578 
579    /***
580     * Old style form to perform a query.
581     * @param xml version of the old style astrogrid query language.
582     * @return XML DOM of Resources queried from the registry. 
583     */
584    public Document submitQuery(Document query) throws RegistryException {       
585       logger.info("submitQuery(Document) - entered submitQueryDOM()");
586       Document doc = null;
587       Document resultDoc = null;
588 
589       try {
590          logger.info("submitQuery(Document) - creating full soap element.");
591          doc = DomHelper.newDocument();
592          Element root = doc.createElementNS(NAMESPACE_URI, "submitQuery");
593          doc.appendChild(root);
594          Node nd = doc.importNode(query.getDocumentElement(), true);
595          root.appendChild(nd);
596       } catch (ParserConfigurationException pce) {
597          throw new RegistryException(pce);
598       }
599 
600       try {
601          return callService(doc,"submitQuery","submitQuery");
602       } catch (RemoteException re) {
603           QueryRegistry qr = new QueryRegistry(conf.getUrl(org.astrogrid.registry.client.RegistryDelegateFactory.ALTQUERY_URL_PROPERTY,null));
604           try {
605               return qr.callService(doc,"submitQuery","submitQuery");
606           }catch(RemoteException re2) {
607               throw new RegistryException(re2);    
608           }catch(ServiceException se2) {
609               throw new RegistryException(se2);
610           }catch(Exception e2) {
611               throw new RegistryException(e2);
612           }
613        } catch(ServiceException se) {
614            throw new RegistryException(se);
615        } catch(Exception e) {
616            throw new RegistryException(e);
617        }
618    }
619 
620    /***
621     * Loads this registry type resource for the registry. Essentially querying
622     * for one resource that defines the Registry.
623     * 
624     * @return XML DOM of Resources queried from the registry. 
625     */
626    public Document loadRegistry() throws RegistryException {
627        
628       logger.info("loadRegistry() - loadRegistry");
629       Document doc = null;
630       Document resultDoc = null;
631       try {
632 
633          DocumentBuilder registryBuilder = null;
634          registryBuilder =
635             DocumentBuilderFactory.newInstance().newDocumentBuilder();
636          doc = registryBuilder.newDocument();
637          Element root = doc.createElementNS(NAMESPACE_URI, "loadRegistry");
638          String value = "http://www.ivoa.net/xml/VOResource/v" + reg_default_version;
639          root.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:vr",value);         
640          doc.appendChild(root);
641       } catch (ParserConfigurationException pce) {
642          throw new RegistryException(pce);
643       }
644       try {
645           return callService(doc,"LoadRegistry","LoadRegistry");
646       } catch (RemoteException re) {
647          throw new RegistryException(re);
648       } catch (ServiceException se) {
649          throw new RegistryException(se);
650       } catch (Exception e) {
651          throw new RegistryException(e);
652       }
653    }
654 
655    /***
656     * Queries for all the authorities managed by this registry. By loading this
657     * registries main registry resource type and looking for the ManagedAuthority
658     * elements, currently does not work with version 0.10.  But is slowly being
659     * factored out of use.
660     * 
661     * @return a hashmap of all the managed authority id's.
662     */
663    public HashMap managedAuthorities() throws RegistryException {
664        
665       logger.info("managedAuthorities() - entered managedAuthorities");
666       HashMap hm = null;
667       Document doc = loadRegistry();
668       if (doc != null) {
669          //try {
670             //System.out.println("the doc in managedAuthorities = " + DomHelper.DocumentToString(doc));
671             //NodeList nl = DomHelper.getNodeListTags(doc, "ManagedAuthority", "vg");
672             NodeList nl = doc.getElementsByTagNameNS("*","ManagedAuthority");            
673             hm = new HashMap();
674             for (int i = 0; i < nl.getLength(); i++) {
675                hm.put(nl.item(i).getFirstChild().getNodeValue(), null);
676             } //for
677          //}catch(IOException ioe) {
678          //   throw new RegistryException(ioe);   
679          //}
680       }       
681       logger.info("managedAuthorities() - exiting managedAuthorities");
682       return hm;
683    }
684 
685    /***
686     * Query for a specific resource in the Registry based on its identifier element(s).
687     * Essentially creates a search query "old style astrogrid" for now.  Based on the identifier.
688     * 
689     * @param identifier IVORN object.
690     * @return XML DOM of Resource queried from the registry. 
691     * @see org.astrogrid.store.Ivorn
692     */
693    public Document getResourceByIdentifier(Ivorn ident)
694       throws RegistryException {
695       if (ident == null) {
696          throw new RegistryException("Cannot call this method with a null ivorn identifier");
697       }
698       return getResourceByIdentifier(ident.getPath());
699    }
700    
701    /***
702     * Query for a specific resource in the Registry based on its identifier element(s).
703     * Essentially creates a search query "old style astrogrid" for now.  Based on the identifier.
704     * 
705     * @param identifier string.
706     * 
707     * @return XML DOM of Resource queried from the registry. 
708     */
709    public Document getResourceByIdentifier(String ident)   
710       throws RegistryException {    
711        Document doc = null;
712        Document resultDoc = null;     
713        
714        logger
715        .info("getResourceByIdentifier(String) - entered getResourceByIdentifierDOM");
716        if (ident == null) {
717            throw new RegistryException("Cannot call this method with a null identifier");
718        }       
719        if (!useCache) {
720            logger.info("GetResourcesByIdentifier() - GetResourcesByIdentifier");
721            try {
722 
723              DocumentBuilder registryBuilder = null;
724              registryBuilder =
725                 DocumentBuilderFactory.newInstance().newDocumentBuilder();
726              doc = registryBuilder.newDocument();
727              Element root = doc.createElementNS(NAMESPACE_URI, "GetResourcesByIdentifier");
728              String value = "http://www.ivoa.net/xml/VOResource/v" + reg_default_version;
729              root.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:vr",value);       
730              Element identElem = doc.createElement("identifier");
731              identElem.appendChild(doc.createTextNode(ident));
732              root.appendChild(identElem);
733              doc.appendChild(root);
734              //System.out.println("the DOC IN GETRESOURCEBYIDNET1 = " + DomHelper.ElementToString(doc.getDocumentElement()));
735           } catch (ParserConfigurationException pce) {
736              throw new RegistryException(pce);
737           }
738           try {
739               resultDoc =  callService(doc,"GetResourcesByIdentifier","GetResourcesByIdentifier");
740               //System.out.println("resultDoc = " + DomHelper.DocumentToString(resultDoc));
741           } catch (RemoteException re) {
742               QueryRegistry qr = new QueryRegistry(conf.getUrl(org.astrogrid.registry.client.RegistryDelegateFactory.ALTQUERY_URL_PROPERTY,null));
743               try {
744                   resultDoc = qr.callService(doc,"GetResourcesByIdentifier","GetResourcesByIdentifier");
745               }catch(RemoteException re2) {
746                   throw new RegistryException(re2);    
747               }catch(ServiceException se2) {
748                   throw new RegistryException(se2);
749               }catch(Exception e2) {
750                   throw new RegistryException(e2);
751               }
752           } catch (ServiceException se) {
753              throw new RegistryException(se);
754           } catch (Exception e) {
755              throw new RegistryException(e);
756           }      
757             NodeList resultList = resultDoc.getElementsByTagNameNS("*","Resource");            
758             if(resultList.getLength() == 0) {
759                throw new RegistryException("No Resource Found for ident = " + ident);   
760             }          
761             if(resultList.getLength() > 1) {
762                throw new RegistryException("Found more than one Resource for Ident = " + ident);   
763             }          
764             logger
765                  .info("getResourceByIdentifier(String) - exiting getResourceByIdentifierDOM (did not use config cache)");
766          return resultDoc;
767        } else {
768             logger
769                  .info("getResourceByIdentifier(String) - exiting getResourceByIdentifierDOM (used config cache)");
770          return conf.getDom(ident);
771        }
772    }
773       
774    public String getQueryForInterfaceType(String type, String version) {
775        String selectQuery = null;
776        
777        if("0.9".equals(version)) {
778        selectQuery = 
779            "<query><selectionSequence>"
780               + "<selection item='searchElements' itemOp='EQ' value='all'/>"
781               + "<selectionOp op='$and$'/>"               
782               + "<selection item='vr:RelatedResource/vr:Relationship' itemOp='EQ' value='derived-from'/>"
783               + "<selectionOp op='AND'/>"
784               + "<selection item='vr:RelatedResource/vr:RelatedTo/vr:Identifier/vr:ResourceKey' itemOp='EQ' value='"
785               + type
786               + "'/>";
787         selectQuery += "</selectionSequence></query>";
788        }else if("0.10".equals(version)) {
789            selectQuery = "<query><selectionSequence>"
790            + "<selection item='searchElements' itemOp='EQ' value='all'/>"
791            + "<selectionOp op='$and$'/>"               
792            + "<selection item='vr:relationship/vr:relationshipType' itemOp='EQ' value='derived-from'/>"
793            + "<selectionOp op='AND'/>"
794            + "<selection item='vr:relationship/vr:relatedResource/@ivo-id' itemOp='EQ' value='ivo://org.astrogrid/"
795            + type
796            + "'/>";
797            selectQuery += "</selectionSequence></query>";
798        }
799         return selectQuery;
800    }
801    
802    
803    public URL[] getEndPointByInterfaceType(InterfaceType interfaceType) throws RegistryException {
804        return getEndPointByInterfaceType(interfaceType,reg_default_version);
805    }
806    
807    public URL[] getEndPointByInterfaceType(InterfaceType interfaceType,String version) throws RegistryException {
808        ServiceData []sd = getResourcesByInterfaceType(interfaceType,version);
809        URL []serviceURL = new URL[sd.length];
810        for(int i = 0;i < sd.length;i++) {
811            serviceURL[i] = sd[i].getAccessURL();
812        }//for
813        return serviceURL;
814        
815    }
816    
817    public ServiceData[] getResourcesByInterfaceType(InterfaceType interfaceType) throws RegistryException  {
818        return getResourcesByInterfaceType(interfaceType,reg_default_version);
819    }
820    
821    public ServiceData[] getResourcesByInterfaceType(InterfaceType interfaceType,String version) throws RegistryException  {
822       Document doc = null;
823       if (interfaceType == null) {
824          throw new RegistryException("No interfaceType defined");
825       }
826       String type = interfaceType.getInterfaceType();
827       logger
828            .info("getResourcesByInterfaceType(InterfaceType) type - " + type);
829        
830       String selectQuery = getQueryForInterfaceType(type,version);
831       doc = submitQuery(selectQuery);          
832          logger
833              .info("getResourcesByInterfaceType(InterfaceType) - exiting getResourcesByInterfaceType");
834          
835          return createServiceData(doc);
836    }
837    
838    private ServiceData[] createServiceData(Document doc) {
839        NodeList nl = doc.getElementsByTagNameNS("*","Resource");
840        ServiceData[] sd = new ServiceData[nl.getLength()];
841        NodeList serviceNodes = null;
842        String authority = null;
843        String resKey = null;
844        for(int i = 0;i < nl.getLength(); i++) {
845            sd[i] = new ServiceData();
846            serviceNodes = ((Element)nl.item(i)).getElementsByTagNameNS("*","Title");
847            if(serviceNodes.getLength() > 0)
848                sd[i].setTitle(DomHelper.getValue((Element)serviceNodes.item(0)));
849            serviceNodes = ((Element)nl.item(i)).getElementsByTagNameNS("*","Description");
850            if(serviceNodes.getLength() > 0)
851                sd[i].setDescription(DomHelper.getValue((Element)serviceNodes.item(0)));
852            serviceNodes = ((Element)nl.item(i)).getElementsByTagNameNS("*","AccessURL");
853            if(serviceNodes.getLength() > 0) {
854                try {
855                    sd[i].setAccessURL(new URL(DomHelper.getValue((Element)serviceNodes.item(0))));
856                }catch(MalformedURLException mfe) {
857                    logger.error(mfe);
858                }
859            }
860            serviceNodes = ((Element)nl.item(i)).getElementsByTagNameNS("*","AuthorityID");
861            if(serviceNodes.getLength() > 0) {
862                authority = DomHelper.getValue((Element)serviceNodes.item(0));
863                serviceNodes = ((Element)nl.item(i)).getElementsByTagNameNS("*","ResourceKey");
864                resKey = DomHelper.getValue((Element)serviceNodes.item(0));
865                if(resKey != null)
866                    sd[i].setIvorn(new Ivorn(authority, resKey,null));
867                else
868                    sd[i].setIvorn(new Ivorn(authority, null, null));
869            }//if
870            //lets skip getting all the interface types for now.
871        }//fors
872        return sd;
873    }
874 
875    /***
876     * Query for a specific resource in the Registry based on its identifier element(s), Then extracts out
877     * the AccessURL element to find the endpoint. If the endpoint is a web service and has a "?wsdl" ending
878     * then attempts to parse the wsdl for the end point of the service.
879     * 
880     * @param ivorn object.
881     * @see org.astrogrid.store.Ivorn 
882     * @return String of a url. 
883     */
884    public String getEndPointByIdentifier(Ivorn ident)
885       throws RegistryException {
886       return getEndPointByIdentifier(ident.getPath());
887    }
888 
889    /***
890     * Query for a specific resource in the Registry based on its identifier element(s), Then extracts out
891     * the AccessURL element to find the endpoint. If the endpoint is a web service and has a "?wsdl" ending
892     * then attempts to parse the wsdl for the end point of the service.
893     * 
894     * @param string identifer of the resource. 
895     * @return String of a url. 
896     */
897    public String getEndPointByIdentifier(String ident)
898       throws RegistryException {
899        logger
900              .info("getEndPointByIdentifier(String) - entered getEndPointByIdentifier with ident = "
901                     + ident);
902       //check for an AccessURL
903       //if AccessURL is their and it is a web service then get the wsdl
904       //into a DOM object and run an XSL on it to get the endpoint.
905       String returnVal, invocation = null;
906       Document doc = getResourceByIdentifier(ident);
907       try {
908          returnVal = DomHelper.getNodeTextValue(doc, "AccessURL", "vr");
909          if(returnVal == null) returnVal = DomHelper.getNodeTextValue(doc, "accessURL", "vr");
910       } catch (IOException ioe) {
911          throw new RegistryException("Could not parse xml to get AcessURL or Invocation");
912       }
913       if (returnVal == null) {
914          throw new RegistryException("Found Resource Document, but had no AccessURL");
915       }
916       logger.info("getEndPointByIdentifier(String) - The AccessURL = " + returnVal);
917       if (returnVal.endsWith("wsdl")) {
918           logger.info("getEndPointByIdentifier(String) - has ?wsdl stripping off");
919          returnVal = returnVal.substring(0,returnVal.indexOf("?wsdl"));
920       }
921       return returnVal;
922    }
923 }