1 package org.astrogrid.registry.server.query;
2
3
4
5 import org.w3c.dom.*;
6
7 import javax.xml.parsers.DocumentBuilderFactory;
8 import javax.xml.parsers.DocumentBuilder;
9
10 import java.io.Reader;
11 import java.io.StringReader;
12 import org.xml.sax.InputSource;
13 import javax.xml.parsers.ParserConfigurationException;
14 import org.xml.sax.SAXException;
15 import java.io.IOException;
16 import org.astrogrid.util.DomHelper;
17 import org.astrogrid.config.Config;
18 import org.astrogrid.registry.server.XQueryExecution;
19 import org.astrogrid.registry.common.XSLHelper;
20 import java.net.URL;
21
22 import java.net.MalformedURLException;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import java.io.*;
27 import org.apache.axis.AxisFault;
28 import org.astrogrid.xmldb.eXist.server.QueryDBService;
29 import org.astrogrid.registry.RegistryException;
30 import org.astrogrid.registry.server.harvest.RegistryHarvestService;
31 import org.astrogrid.registry.server.RegistryServerHelper;
32 import org.astrogrid.registry.server.QueryHelper;
33
34 import java.util.ArrayList;
35
36 /***
37 *
38 *
39 *
40 * @see org.astrogrid.registry.common.RegistryInterface
41 * @link http://www.ivoa.net/twiki/bin/view/IVOA/IVOARegWp03
42 * @author Kevin Benson
43 */
44 public class RegistryQueryService {
45
46 /***
47 * Logging variable for writing information to the logs
48 */
49 private static final Log log = LogFactory.getLog(RegistryService.class);
50
51 /***
52 * conf - Config variable to access the configuration for the server normally
53 * jndi to a config file.
54 * @see org.astrogrid.config.Config
55 */
56 public static Config conf = null;
57
58 /***
59 * final variable for the default AuthorityID associated to this registry.
60 */
61 private static final String AUTHORITYID_PROPERTY =
62 "org.astrogrid.registry.authorityid";
63
64 /***
65 * Static to be used on the initiatian of this class for the config
66 */
67 static {
68 if(conf == null) {
69 conf = org.astrogrid.config.SimpleConfig.getSingleton();
70 }
71 }
72
73 /***
74 * Search - Web Service method to take ADQL DOM and perform a query on the
75 * registry. Takes in a DOM so it can handle multiple versions of ADQL.
76 *
77 * @param query - DOM object containing ADQL.
78 * @throws - AxisFault containing exceptions that might have occurred setting up
79 * or querying the registry.
80 * @return - Resource DOM object of the Resources from the query of the registry.
81 *
82 */
83 public Document Search(Document query) throws AxisFault {
84 log.debug("start Search");
85 long beginQ = System.currentTimeMillis();
86 XSLHelper xslHelper = new XSLHelper();
87
88
89 String attrVersion = getRegistryVersion(query);
90 String versionNumber = attrVersion.replace('.','_');
91
92
93 String xqlQuery = getQuery(query,versionNumber);
94 log.info("The XQLQuery = " + xqlQuery);
95
96
97 String collectionName = "astrogridv" + versionNumber;
98 log.info("Collection Name for query = " + collectionName);
99
100
101 Document resultDoc = queryExist(xqlQuery,collectionName);
102 log.info("Time taken to complete search on server = " +
103 (System.currentTimeMillis() - beginQ));
104 log.debug("end Search");
105 if(resultDoc != null) {
106 log.info("Number of Resources to be returned = " +
107 resultDoc.getElementsByTagNameNS("*","Resource").getLength());
108 }
109
110
111
112 return xslHelper.transformExistResult((Node)resultDoc,
113 versionNumber,"SearchResponse");
114 }
115
116
117 /***
118 * More of a convenience method to do direct Xqueries on the registry
119 * Gets the XQuery out of the XQLString element which is the wrapped method
120 * name in the SOAP body.
121 *
122 * @param query - XQuery string to be used directly on the registry.
123 * @throws - AxisFault containing exceptions that might have occurred setting up
124 * or querying the registry.
125 * @return - Resource DOM object of the Resources from the query of the registry.
126 */
127 public Document Query(Document query) throws AxisFault {
128 log.debug("start Query");
129 Document resultDoc = null;
130 try {
131
132 String xql = DomHelper.getNodeTextValue(query,"XQLString");
133 log.debug("end Query");
134
135 String attrVersion = getRegistryVersion(query);
136 String versionNumber = attrVersion.replace('.','_');
137
138 String collectionName = "astrogridv" + versionNumber;
139 log.info("Collection Name for query = " + collectionName);
140
141 resultDoc = queryExist(xql,collectionName);
142 if(resultDoc != null) {
143 log.info("Number of Resources to be returned = " +
144 resultDoc.getElementsByTagNameNS("*","Resource").getLength());
145 }
146 }catch(IOException ioe) {
147 throw new AxisFault("IO problem", ioe);
148 }
149 return resultDoc;
150 }
151
152 /***
153 * More of a convenience method to do direct Xqueries on the registry
154 * and this method is for when a Web Service style does not wrap a method name
155 * in the soap body.
156
157 * @param query - XQuery string to be used directly on the registry.
158 * @throws - AxisFault containing exceptions that might have occurred setting up
159 * or querying the registry.
160 * @return - Resource DOM object of the Resources from the query of the registry.
161 */
162 public Document XQLString(Document query) throws AxisFault {
163 log.debug("start XQLString");
164 Document resultDoc = null;
165 try {
166 String attrVersion = getRegistryVersion(query);
167 String versionNumber = attrVersion.replace('.','_');
168
169 String collectionName = "astrogridv" + versionNumber;
170 log.info("Collection Name for query = " + collectionName);
171
172 String xql = DomHelper.getNodeTextValue(query,"XQLString");
173 log.debug("end XQLString");
174 resultDoc = queryExist(xql,collectionName);
175 if(resultDoc != null) {
176 log.info("Number of Resources to be returned = " +
177 resultDoc.getElementsByTagNameNS("*","Resource").getLength());
178 }
179 }catch(IOException ioe) {
180 throw new AxisFault("IO problem", ioe);
181 }
182 return resultDoc;
183
184 }
185
186 /***
187 * submitQuery queries the registry for Resources. Currently uses
188 * an older xml query language that Astrogrid came up with, but will
189 * soon be rarely used for the ADQL version to be the standard for the
190 * IVOA. Will be deprecated in itn07.
191 *
192 * @param query XML document object representing the query language used on the registry.
193 * @throws - AxisFault containing exceptions that might have occurred setting up
194 * or querying the registry.
195 * @return XML docuemnt object representing the result of the query.
196 * @author Kevin Benson
197 */
198 public Document submitQuery(Document query) throws AxisFault {
199 log.debug("start submitQuery");
200 long beginQ = System.currentTimeMillis();
201 XSLHelper xslHelper = new XSLHelper();
202
203 String attrVersion = getRegistryVersion(query);
204 String versionNumber = attrVersion.replace('.','_');
205 String collectionName = "astrogridv" + versionNumber;
206 log.info("Collection Name for query = " + collectionName);
207
208
209 String xql = RegistryServerHelper.getXQLDeclarations(versionNumber) + XQueryExecution.createXQL(query);
210 log.info("Query to be performed on the db = " + xql);
211 Document resultDoc = queryExist(xql,collectionName);
212 log.info("Time taken to complete submitQuery on server = " +
213 (System.currentTimeMillis() - beginQ));
214 if(resultDoc != null) {
215 log.info("Number of Resources to be returned = " +
216 resultDoc.getElementsByTagNameNS("*","Resource").getLength());
217 }
218 log.debug("end submitQuery");
219
220
221
222 return xslHelper.transformExistResult((Node)resultDoc,versionNumber,null);
223 }
224
225 /***
226 * Queries for the Registry Resource element that is tied to this Registry.
227 * All Astrogrid Registries have one Registry Resource tied to the Registry.
228 * Which defines the AuthorityID's it manages and how to access the Registry.
229 *
230 * @param query actually normally empty/null and is ignored.
231 * @throws - AxisFault containing exceptions that might have occurred setting up
232 * or querying the registry.
233 * @return XML docuemnt object representing the result of the query.
234 */
235 public Document loadRegistry(Document query) throws AxisFault {
236 log.debug("start loadRegistry");
237
238
239 Document doc = null;
240 Document responseDoc = null;
241 String attrVersion = getRegistryVersion(query);
242 String versionNumber = attrVersion.replace('.','_');
243 log.info("the versionNumber in loadRegistry = " + versionNumber);
244 return loadMainRegistry(versionNumber);
245 }
246
247 public Document loadMainRegistry(String versionNumber) throws AxisFault {
248 long beginQ = System.currentTimeMillis();
249 String collectionName = "astrogridv" + versionNumber;
250 log.info("Collection Name for query = " + collectionName);
251 String xqlString = QueryHelper.queryForMainRegistry(versionNumber);
252 log.info("XQL String = " + xqlString);
253 Document resultDoc = queryExist(xqlString,collectionName);
254
255 XSLHelper xslHelper = new XSLHelper();
256 log.info("Time taken to complete loadRegistry on server = " +
257 (System.currentTimeMillis() - beginQ));
258 log.debug("end loadRegistry");
259
260
261
262 return xslHelper.transformExistResult((Node)resultDoc,versionNumber,null);
263 }
264
265 /***
266 * Queries the eXist xml database, on the collection of the registry.
267 * @param xqlString an XQuery to query the database
268 * @param collectionName the location in the database to query (sort of like a table)
269 * @return xml DOM object returned from the database, which are Resource elements
270 * @throws - AxisFault containing exceptions that might have occurred setting up
271 * or querying the registry.
272 */
273 private Document queryExist(String xqlString, String collectionName) throws AxisFault {
274 log.debug("start queryExist");
275 QueryDBService qdb = new QueryDBService();
276 return qdb.query(collectionName,xqlString);
277 }
278
279 public ArrayList getAstrogridVersions() {
280 QueryDBService qdb = new QueryDBService();
281 ArrayList al = new ArrayList();
282 try {
283 Document doc = qdb.getCollection("");
284 String xml = DomHelper.DocumentToString(doc);
285 int index = -1;
286 int temp = 0;
287
288 while((index = xml.indexOf("astrogridv",temp)) != -1) {
289 temp = xml.indexOf("\"", index+10);
290 System.out.println("adding to the arraylist = " + ((String)xml.substring(index+10,temp)));
291 al.add(((String)xml.substring(index+10,temp)));
292 }
293 }catch(MalformedURLException mue) {
294 mue.printStackTrace();
295 }catch(ParserConfigurationException pce) {
296 pce.printStackTrace();
297 }catch(IOException ioe) {
298 ioe.printStackTrace();
299 }catch(SAXException sax) {
300 sax.printStackTrace();
301 }
302 return al;
303 }
304
305 public Document keywordQuery(String keywords, boolean orKeywords) throws AxisFault {
306 return keywordQuery(keywords,orKeywords,RegistryServerHelper.getDefaultVersionNumber());
307 }
308
309 public Document keywordQuery(String keywords, boolean orKeywords, String version) throws AxisFault {
310 long beginQ = System.currentTimeMillis();
311 if(version == null || version.trim().length() <= 0) {
312 version = RegistryServerHelper.getDefaultVersionNumber();
313 }
314 String versionNumber = version.replace('.','_');
315 String []keyword = keywords.split(" ");
316 String xqlPaths = conf.getString("keyword.query.path." + versionNumber);
317 String []xqlPath = xqlPaths.split(",");
318
319
320 String xqlString = QueryHelper.getStartQuery(versionNumber);
321 for(int i = 0;i < xqlPath.length;i++) {
322 xqlString += "(";
323 for(int j = 0;j < keyword.length;j++) {
324 xqlString += xqlPath[i] + " &= '*" + keyword[j] + "*'";
325 if(j != (keyword.length - 1)) {
326 if(orKeywords) {
327 xqlString += " or ";
328 }else {
329 xqlString += " and ";
330 }
331 }
332 }
333 xqlString += ") ";
334 if(i != (xqlPath.length-1)) {
335 xqlString += " or ";
336 }
337 }
338 xqlString += " return $x";
339
340 String collectionName = "astrogridv" + versionNumber;
341 Document resultDoc = queryExist(xqlString,collectionName);
342 if(resultDoc != null) {
343 log.info("Number of Resources to be returned = " +
344 resultDoc.getElementsByTagNameNS("*","Resource").getLength());
345 }
346 XSLHelper xslHelper = new XSLHelper();
347 log.info("Time taken to complete keywordsearch on server = " +
348 (System.currentTimeMillis() - beginQ));
349 log.debug("end keywordsearch");
350
351
352
353 return xslHelper.transformExistResult((Node)resultDoc,
354 versionNumber,"KeywordSearchResponse");
355 }
356
357 public Document getAll(String versionNumber) throws AxisFault {
358 XSLHelper xslHelper = new XSLHelper();
359 if(versionNumber == null || versionNumber.trim().length() <= 0) {
360 versionNumber = RegistryServerHelper.getDefaultVersionNumber();
361 }
362 String queryVersion = versionNumber.replace('.','_');
363 String collectionName = "astrogridv" + queryVersion;
364 log.info("collname=" + collectionName);
365 String xqlString = QueryHelper.getAllQuery(queryVersion);
366 Document resultDoc = queryExist(xqlString,collectionName);
367 return xslHelper.transformExistResult((Node)resultDoc,
368 queryVersion,"GetAllResponse");
369 }
370
371 public Document GetResourcesByIdentifier(Document query) throws AxisFault {
372 log.debug("start GetResourcesByIdentifier");
373 String ident = null;
374 try {
375 ident = DomHelper.getNodeTextValue(query,"identifier");
376 log.info("found identifier in web service request = " + ident);
377 }catch(IOException ioe) {
378 throw new AxisFault("IO problem trying to get identifier");
379 }
380 String attrVersion = getRegistryVersion(query);
381 return getResourcesByIdentifier(ident,attrVersion);
382 }
383
384 public Document getResourcesByIdentifier(String ivorn, String versionNumber) throws AxisFault {
385 XSLHelper xslHelper = new XSLHelper();
386 if(versionNumber == null || versionNumber.trim().length() <= 0) {
387 versionNumber = RegistryServerHelper.getDefaultVersionNumber();
388 }
389 if(ivorn == null || ivorn.trim().length() <= 0) {
390 throw new AxisFault("Cannot have empty or null identifier");
391 }
392 String queryVersion = versionNumber.replace('.','_');
393 String collectionName = "astrogridv" + queryVersion;
394 String xqlString = QueryHelper.queryForResource(ivorn,queryVersion);
395 Document resultDoc = queryExist(xqlString,collectionName);
396 return xslHelper.transformExistResult((Node)resultDoc,
397 queryVersion,"GetResourceByIdentifier");
398 }
399
400 public Document getResourcesByAnyIdentifier(String ivorn, String versionNumber) throws AxisFault {
401 XSLHelper xslHelper = new XSLHelper();
402 if(versionNumber == null || versionNumber.trim().length() <= 0) {
403 versionNumber = RegistryServerHelper.getDefaultVersionNumber();
404 }
405 String queryVersion = versionNumber.replace('.','_');
406 String collectionName = "astrogridv" + queryVersion;
407 String xqlString = QueryHelper.queryForAllResource(ivorn,queryVersion);
408 Document resultDoc = queryExist(xqlString,collectionName);
409 return xslHelper.transformExistResult((Node)resultDoc,
410 queryVersion,"GetResourceByIdentifier");
411 }
412
413 public Document getResourcesByAuthority(String ivorn, String versionNumber) throws AxisFault {
414 XSLHelper xslHelper = new XSLHelper();
415 if(versionNumber == null || versionNumber.trim().length() <= 0) {
416 versionNumber = RegistryServerHelper.getDefaultVersionNumber();
417 }
418 String queryVersion = versionNumber.replace('.','_');
419 String collectionName = "astrogridv" + queryVersion;
420 String xqlString = QueryHelper.queryForResourceByAuthority(ivorn,queryVersion);
421 Document resultDoc = queryExist(xqlString,collectionName);
422 return xslHelper.transformExistResult((Node)resultDoc,
423 queryVersion,"GetResourceByAuthroity");
424 }
425
426
427 public Document KeywordSearch(Document query) throws AxisFault {
428 log.debug("start keywordsearch");
429 String keywords = null;
430 String orValue = null;
431 try {
432 keywords = DomHelper.getNodeTextValue(query,"keywords");
433 orValue = DomHelper.getNodeTextValue(query,"orValue");
434 }catch(IOException ioe) {
435 throw new AxisFault("IO problem trying to get keywords and orValue");
436 }
437 String attrVersion = getRegistryVersion(query);
438 boolean orKeywords = new Boolean(orValue).booleanValue();
439 return keywordQuery(keywords,orKeywords,attrVersion);
440 }
441
442 /***
443 * Queries and returns all the Resources that are Registry type resources.
444 * Used by other registries as a convenience query to discover other
445 * regiestries not known for harvesting.
446 *
447 * @param query normally empty and is ignored, it is required though for the
448 * Axis Document style method. At most it will contain nothing more than the method
449 * name.
450 * @return Resource entries of type Registries.
451 * @throws - AxisFault containing exceptions that might have occurred setting up
452 * or querying the registry.
453 */
454 public Document GetRegistries(Document query) throws AxisFault {
455
456
457 String attrVersion = getRegistryVersion(query);
458 String versionNumber = attrVersion.replace('.','_');
459 return getRegistriesQuery(versionNumber);
460 }
461
462 public Document getRegistriesQuery(String versionNumber) throws AxisFault {
463 long beginQ = System.currentTimeMillis();
464 if(versionNumber == null || versionNumber.trim().length() <= 0) {
465 versionNumber = RegistryServerHelper.getDefaultVersionNumber();
466 }
467 String queryVersion = versionNumber.replace('.','_');
468 String collectionName = "astrogridv" + queryVersion;
469 log.info("Collection Name for query = " + collectionName);
470
471
472 String xqlString = QueryHelper.queryForRegistries(queryVersion);
473 log.info("XQL String = " + xqlString);
474 Document resultDoc = queryExist(xqlString,collectionName);
475 XSLHelper xslHelper = new XSLHelper();
476 log.info("Time taken to complete GetRegistries on server = " +
477 (System.currentTimeMillis() - beginQ));
478 log.debug("end loadRegistry");
479
480 return xslHelper.transformExistResult((Node)resultDoc,
481 queryVersion,"GetRegistriesResponse");
482 }
483
484 /***
485 * Used by all the OAI required method interfaces to get the OAI
486 * conformed Resources from a URL. This URL is a servlet to query
487 * the eXist database and put the XML in a OAI form. The XML DOM returned
488 * are all the Resources managed by this Registry.
489 * @param oaiServlet a url string
490 * @return OAI conformed DOM object of all the Resourced managed by this Registry.
491 * @throws - AxisFault containing exceptions that might have occurred setting up
492 * or querying the registry.
493 */
494 private Document queryOAI(String oaiServlet) throws AxisFault {
495 try {
496 log.info("the oaiservlet url = '" + oaiServlet + "'");
497 return DomHelper.newDocument(new URL(oaiServlet));
498 }catch(MalformedURLException me) {
499 throw new AxisFault("Incorrect url for calling oai servlet", me);
500 }catch(ParserConfigurationException pce) {
501 throw new AxisFault("Parser Config error", pce);
502 }catch(SAXException sax) {
503 throw new AxisFault("SAX problem parsing xml" , sax);
504 }catch(IOException ioe) {
505 throw new AxisFault("IO Problem", ioe);
506 }
507 }
508
509 private String getOAIServletURL(Document query) {
510 String attrVersion = getRegistryVersion(query);
511 String versionNumber = attrVersion.replace('.','_');
512 return conf.getString("oai.servlet.url." + versionNumber);
513 }
514
515 /***
516 * OAI-Identify conformed Web service method.
517 *
518 * @param query actually this OAI mehtod requires nothing.
519 * @return XML DOM object conforming to the OAI Identify.
520 * @throws - AxisFault containing exceptions that might have occurred
521 * calling the servlet/url.
522 * @link http://www.openarchives.org
523 */
524 public Document Identify(Document query) throws AxisFault {
525 String oaiServlet = getOAIServletURL(query) + "?verb=Identify";
526 Document resultDoc = queryOAI(oaiServlet);
527 Element currentRoot = resultDoc.getDocumentElement();
528 Element root = resultDoc.createElement("IdentifyResponse");
529 root.appendChild(currentRoot);
530 resultDoc.appendChild(root);
531 return resultDoc;
532 }
533
534 /***
535 * OAI-ListMetadataFormats conformed Web service method.
536 *
537 * @param query contains an optional identifier string.
538 * @return XML DOM object conforming to the OAI ListMetadataFormats.
539 * @throws - AxisFault containing exceptions that might have occurred
540 * calling the servlet/url.
541 * @link http://www.openarchives.org
542 */
543 public Document ListMetadataFormats(Document query) throws AxisFault {
544 String oaiServlet = getOAIServletURL(query) + "?verb=ListMetadataFormats";
545 NodeList nl = null;
546 if( (nl = query.getElementsByTagName("identifier")).getLength() > 0 )
547 oaiServlet += "&identifier=" + nl.item(0).getFirstChild().getNodeValue();
548 Document resultDoc = queryOAI(oaiServlet);
549 Element currentRoot = resultDoc.getDocumentElement();
550 Element root = resultDoc.createElement("ListMetadataFormatsResponse");
551 root.appendChild(currentRoot);
552 resultDoc.appendChild(root);
553 return resultDoc;
554 }
555
556 /***
557 * OAI-ListSets conformed Web service method. Currently not implemented.
558 *
559 * @param query
560 * @return XML DOM object conforming to the OAI OAI-ListSets.
561 * @throws - AxisFault containing exceptions that might have occurred
562 * calling the servlet/url.
563 * @link http://www.openarchives.org
564 */
565 public Document ListSets(Document query) throws AxisFault {
566 throw new AxisFault("Sorry but this method is currently not implemented");
567 }
568
569 /***
570 * OAI-ResumeListSets conformed Web service method. Currently not implemented.
571 *
572 * @param query
573 * @return XML DOM object conforming to the OAI OAI-ResumeListSets.
574 * @throws - AxisFault containing exceptions that might have occurred
575 * calling the servlet/url.
576 * @link http://www.openarchives.org
577 */
578 public Document ResumeListSets(Document query) throws AxisFault {
579 throw new AxisFault("Sorry but this method is currently not implemented");
580 }
581
582 /***
583 * OAI-GetRecord conformed Web service method.
584 *
585 * @param query contains an identifier string and metadataPrefix. The prefix
586 * is defaulted to the standard registry ivo_vor if not given.
587 * @return XML DOM object conforming to the OAI GetRecord.
588 * @throws - AxisFault containing exceptions that might have occurred
589 * calling the servlet/url.
590 * @link http://www.openarchives.org
591 */
592 public Document GetRecord(Document query) throws AxisFault {
593 String oaiServlet = getOAIServletURL(query) + "?verb=GetRecord";
594 NodeList nl = null;
595 if( (nl = query.getElementsByTagName("identifier")).getLength() > 0 )
596 oaiServlet += "&identifier=" + nl.item(0).getFirstChild().getNodeValue();
597 else
598 throw new AxisFault("No Identifier given");
599 if( (nl = query.getElementsByTagName("metadataPrefix")).getLength() > 0 )
600 oaiServlet += "&metadataPrefix=" + nl.item(0).getFirstChild().getNodeValue();
601 else
602 oaiServlet += "&metadataPrefix=ivo_vor";
603 Document resultDoc = queryOAI(oaiServlet);
604
605 Element currentRoot = resultDoc.getDocumentElement();
606 Element root = resultDoc.createElement("GetRecordResponse");
607 root.appendChild(currentRoot);
608 resultDoc.appendChild(root);
609 return resultDoc;
610 }
611
612 /***
613 * OAI-ListIdentifiers conformed Web service method.
614 *
615 * @param query contains a metadataPrefix, and optional from and until
616 * @return XML DOM object conforming to the OAI ListIdentifiers.
617 * @throws - AxisFault containing exceptions that might have occurred
618 * calling the servlet/url.
619 * @link http://www.openarchives.org
620 */
621 public Document ListIdentifiers(Document query) throws AxisFault {
622 String oaiServlet = getOAIServletURL(query) + "?verb=ListIdentifiers";
623 NodeList nl = null;
624 if( (nl = query.getElementsByTagName("metadataPrefix")).getLength() > 0 )
625 oaiServlet += "&metadataPrefix=" + nl.item(0).getFirstChild().getNodeValue();
626 else
627 oaiServlet += "&metadataPrefix=ivo_vor";
628 if( (nl = query.getElementsByTagName("from")).getLength() > 0 )
629 oaiServlet += "&from=" + nl.item(0).getFirstChild().getNodeValue();
630 if( (nl = query.getElementsByTagName("until")).getLength() > 0 )
631 oaiServlet += "&until=" + nl.item(0).getFirstChild().getNodeValue();
632 Document resultDoc = queryOAI(oaiServlet);
633 Element currentRoot = resultDoc.getDocumentElement();
634 Element root = resultDoc.createElement("ListIdentifiersResponse");
635 root.appendChild(currentRoot);
636 resultDoc.appendChild(root);
637 return resultDoc;
638
639 }
640
641 /***
642 * OAI-ResumeListIdentifiers conformed Web service method.
643 *
644 * @param query contains a resumptionToken
645 * @return XML DOM object conforming to the OAI ResumeListIdentifiers.
646 * @throws - AxisFault containing exceptions that might have occurred
647 * calling the servlet/url.
648 * @link http://www.openarchives.org
649 */
650 public Document ResumeListIdentifiers(Document query) throws AxisFault {
651 String oaiServlet = getOAIServletURL(query);
652 NodeList nl = null;
653 if( (nl = query.getElementsByTagName("resumptionToken")).getLength() > 0 )
654 oaiServlet += "?resumptionToken=" + nl.item(0).getFirstChild().getNodeValue();
655 else
656 throw new AxisFault("No resumptionToken found in ResumeListIdentifiers");
657 Document resultDoc = queryOAI(oaiServlet);
658 Element currentRoot = resultDoc.getDocumentElement();
659 Element root = resultDoc.createElement("ResumeListIdentifiersResponse");
660 root.appendChild(currentRoot);
661 resultDoc.appendChild(root);
662 return resultDoc;
663 }
664
665 /***
666 * OAI-ListRecords conformed Web service method.
667 *
668 * @param query contains a metadataPrefix, optional from&until elements.
669 * @return XML DOM object conforming to the OAI ListRecords.
670 * @throws - AxisFault containing exceptions that might have occurred
671 * calling the servlet/url.
672 * @link http://www.openarchives.org
673 */
674 public Document ListRecords(Document query) throws AxisFault {
675 String oaiServlet = getOAIServletURL(query) + "?verb=ListRecords";
676 NodeList nl = null;
677 if( (nl = query.getElementsByTagName("metadataPrefix")).getLength() > 0 )
678 oaiServlet += "&metadataPrefix=" + nl.item(0).getNodeValue();
679 else
680 oaiServlet += "&metadataPrefix=ivo_vor";
681 if( (nl = query.getElementsByTagName("from")).getLength() > 0 )
682 oaiServlet += "&from=" + nl.item(0).getFirstChild().getNodeValue();
683 if( (nl = query.getElementsByTagName("until")).getLength() > 0 )
684 oaiServlet += "&until=" + nl.item(0).getFirstChild().getNodeValue();
685 Document resultDoc = queryOAI(oaiServlet);
686 Element currentRoot = resultDoc.getDocumentElement();
687 Element root = resultDoc.createElement("ListRecordsResponse");
688 root.appendChild(currentRoot);
689 resultDoc.appendChild(root);
690 return resultDoc;
691 }
692
693 /***
694 * OAI-ResumeListRecords conformed Web service method.
695 *
696 * @param query contains a resumptionToken
697 * @return XML DOM object conforming to the OAI ResumeListRecords.
698 * @throws - AxisFault containing exceptions that might have occurred
699 * calling the servlet/url.
700 * @link http://www.openarchives.org
701 */
702 public Document ResumeListRecords(Document query) throws AxisFault {
703 String oaiServlet = getOAIServletURL(query);
704 NodeList nl = null;
705 if( (nl = query.getElementsByTagName("resumptionToken")).getLength() > 0 )
706 oaiServlet += "?resumptionToken=" + nl.item(0).getFirstChild().getNodeValue();
707 else
708 throw new AxisFault("No resumptionToken found in ResumeListRecords");
709 Document resultDoc = queryOAI(oaiServlet);
710 Element currentRoot = resultDoc.getDocumentElement();
711 Element root = resultDoc.createElement("ResumeListRecordsResponse");
712 root.appendChild(currentRoot);
713 resultDoc.appendChild(root);
714 return resultDoc;
715 }
716
717 /***
718 * Transforms ADQL to XQuery, uses the namespace of ADQL to allow the
719 * transformations to handle different versions. Transformations are done
720 * by XSL stylesheets.
721 *
722 * @param query ADQL DOM object
723 * @return xquery string
724 * @throws - AxisFault containing exceptions that might have occurred
725 * calling the servlet/url.
726 */
727 private String getQuery(Document query,String resourceVersion) throws AxisFault {
728 XSLHelper xslHelper = new XSLHelper();
729 NodeList nl = query.getElementsByTagNameNS("*","Select");
730
731 if(nl.getLength() == 0)
732 nl = query.getElementsByTagNameNS("*","Where");
733
734
735
736 String adqlVersion = null;
737 log.info("the adql in getquery nl.getLenth = " + nl.getLength());
738 if(nl.getLength() > 0) {
739 log.info("the namespaceuri for element = " + ((Element)nl.item(0)).getNamespaceURI());
740 adqlVersion = ((Element)nl.item(0)).getNamespaceURI();
741
742
743
744
745
746
747 }
748
749
750 if(adqlVersion == null || adqlVersion.trim().length() == 0) {
751 throw new AxisFault("Could not find a version of the ADQL");
752 }
753
754 adqlVersion = adqlVersion.substring(adqlVersion.lastIndexOf("v")+1);
755 adqlVersion = adqlVersion.replace('.','_');
756
757 return xslHelper.transformADQLToXQL(query, adqlVersion,
758 RegistryServerHelper.getRootNodeName(resourceVersion),
759 RegistryServerHelper.getXQLDeclarations(resourceVersion));
760 }
761
762 /***
763 * Looks for a registry version number in a DOM object. By looking at the xmlns
764 * (normally vr) of varoius elements. Because a Resource element may be a few
765 * elements down it goes through a few child nodes.
766 *
767 * @param query XML DOM of Resources
768 * @return version number of the Registry.
769 */
770 private String getRegistryVersion(Document query) {
771 log.info("in getRegistryversion");
772
773 if(query == null) {
774 return RegistryServerHelper.getRegistryVersionFromNode(query);
775 }
776 Element elem = query.getDocumentElement();
777 if(elem == null) {
778 return RegistryServerHelper.getRegistryVersionFromNode(query);
779 }
780 if(elem.hasChildNodes()) {
781 return RegistryServerHelper.getRegistryVersionFromNode(
782 query.getDocumentElement().getFirstChild());
783 }
784 return RegistryServerHelper.getRegistryVersionFromNode(
785 query.getDocumentElement());
786 }
787
788 public Document harvestResource(Document resources) throws AxisFault {
789 RegistryHarvestService rhs = new RegistryHarvestService();
790 try {
791 rhs.harvestResource(resources,null);
792 }catch(IOException ioe) {
793 throw new AxisFault("IOE problem",ioe);
794 }catch(RegistryException re) {
795 throw new AxisFault("Registry exception", re);
796 }
797 return resources;
798 }
799
800 }